當操做信號量(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。ide
I.SEM_UNDO示例url
i.創建包含兩個信號量的信號量集,第一個信號量置20,第二個信號量置10spa
[plain] view plain copy.net
[redhat@localhost sem]$ ipcmk -S 2 orm
Semaphore id: 131075 blog
[redhat@localhost sem]$ ./seminfo 進程
command : ./seminfo semid ip
[redhat@localhost sem]$ ./seminfo 131075 get
key:585c7c37 it
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