当操作信号量(semop)时,sem_flg可以设置SEM_UNDO标识;SEM_UNDO用于将修改的信号量值在进程正常退出(调用exit退出或main执行完)或异常退出(如段异常、除0异常、收到KILL信号等)时归还给信号量。
如信号量初始值是20,进程以SEM_UNDO方式操作信号量减2,减5,加1;在进程未退出时,信号量变成20-2-5+1=14;在进程退出时,将修改的值归还给信号量,信号量变成14+2+5-1=20。
I.SEM_UNDO示例
i.建立包含两个信号量的信号量集,第一个信号量置20,第二个信号量置10
[plain] view plain copy
[redhat@localhost sem]$ ipcmk -S 2
Semaphore id: 131075
[redhat@localhost sem]$ ./seminfo
command : ./seminfo semid
[redhat@localhost sem]$ ./seminfo 131075
key:585c7c37
semid:131075
nsems:2
-------sem details---------
semnum:0, semval:0
semnum:1, semval:0
[redhat@localhost sem]$ ./semop
command : ./semop semid semnum semops undo[0|1] sleeps[0-15]
[redhat@localhost sem]$ ./semop 131075 0 20 0 0
[redhat@localhost sem]$ ./semop 131075 1 10 0 0
[redhat@localhost sem]$ ./seminfo 131075
key:585c7c37
semid:131075
nsems:2
-------sem details---------
semnum:0, semval:20
semnum:1, semval:10
ii.不设置SEM_UNDO,将第一个信号量减2;进程未退出时,信号量由20变成18;进程正常退出时,保持18不变。
设置SEM_UNDO,将第二个信号量减2;进程未退出时,信号量由10变成8;进程正常退出时,将2归还给信号量,信号量重新变回10
[plain] view plain copy
[redhat@localhost sem]$ ./semop 131075 0 -2 0 0
[redhat@localhost sem]$ ./semop 131075 1 -2 1 15 &
[1] 3339
[redhat@localhost sem]$ ./seminfo 131075
key:585c7c37
semid:131075
nsems:2
-------sem details---------
semnum:0, semval:18
semnum:1, semval:8
[redhat@localhost sem]$ ./seminfo 131075
key:585c7c37
semid:131075
nsems:2
-------sem details---------
semnum:0, semval:18
semnum:1, semval:8
[redhat@localhost sem]$ ./seminfo 131075
key:585c7c37
semid:131075
nsems:2
-------sem details---------
semnum:0, semval:18
semnum:1, semval:10
[1]+ Done ./semop 131075 1 -2 1 15
iii.不设置SEM_UNDO,将第一个信号量减2;进程未退出时,信号量由18变成16;进程非正常退出时,保持16不变。
设置SEM_UNDO,将第二个信号量减2;进程未退出时,信号量由10变成8;进程非正常退出时,将2归还给信号量,信号量重新变回10
[plain] view plain copy
[redhat@localhost sem]$ ./semop 131075 0 -2 0 10 & ./semop 131075 1 -2 1 15&
[1] 3352
[2] 3353
[redhat@localhost sem]$ ./seminfo 131075
key:585c7c37
semid:131075
nsems:2
-------sem details---------
semnum:0, semval:16
semnum:1, semval:8
[redhat@localhost sem]$ kill -9 3073
[redhat@localhost sem]$ kill -9 3074
[redhat@localhost sem]$ ./seminfo 131075
key:585c7c37
semid:131075
nsems:2
-------sem details---------
semnum:0, semval:16
semnum:1, semval:10
[2]+ 已杀死 ./semop 131075 1 -2 1 15
转载于:https://blog.51cto.com/xiexiankun/1830100