unix或linux實現p,v操作,主要是通過訊號等操作來實現。
訊號燈的建立和獲取通過呼叫semget函式來實現 例如mysem_id=semget(sem_key,semsize,ipc_creat|0666)),其中sem_key為欲建立或呼叫的訊號燈的鍵值,可以自己定義 比如#define sem_key 7589 ,semsize 為訊號等的數量,semget實際是得到乙個訊號燈陣列,這個陣列的長度可以自己定義 #define semsize 5 這樣就得到了乙個訊號燈數量為5的訊號燈陣列。建立或取得訊號等陣列後,可以對各個訊號燈進行賦值。一下為賦值函式
/*** s_id 第s_id個訊號燈
* ini_value 初始值
*/void init_mysemvalue(int s_id,int ini_value)
}/*arg.array = (unsigned short *) calloc(semsize,sizeof(unsigned short));
if(arg.array == null)
arg.array[s_id] = ini_value;*/
arg.val = ini_value;
if(semctl(mysem_id,s_id,setval,arg) == -1)
}其中 union semun 的定義為
union semun;
取得指定的訊號等的當前值
int getmysemvalue(int s_id)
}i_value = semctl(mysem_id,s_id,getval);
if(i_value == -1)
return i_value;
}mywait用於對訊號等進可回滾的p操作,可回滾的意思是,當對訊號燈進行p操作的程序因為某些意外或者有意識的退出(死亡)後,訊號等將自動恢復到操作前的狀態,例如某個程序因為做了p操作阻塞了,在阻塞過程中被人人為的kill掉,該程序死後,系統講自動的對該訊號量做一次v操作以保持平衡,這樣的好處是在進行互斥操作的多程序程式不會因為某個程序只做p操作而未做v操作就退出後,發生死鎖行為。
void mywait(int s_id)
perror("semop err!/n");
exit(-1);}}
mysignal對訊號燈進行可回滾的v操作,回滾的好處和剛才的mywait一樣
void mysignal(int s_id)
perror("semop err!/n");
exit(-1);}}
myuwait 是對訊號燈進行不可回滾的p操作,使用起來要各位小心。否則容易發生死鎖
void myuwait(int s_id)
perror("semop err!/n");
exit(-1);}}
myusignal是對訊號燈進行不可回滾的v操作
void myusignal(int s_id)
perror("semop err!/n");
exit(-1);}}
需要注意的是多某個訊號燈變數做可回滾的p操作,就必須使用可回滾的v操作,就是說如果對某個訊號燈用mywait操作,就必須使用mysignal做v操作,而不能使用myusignal,並且其他地方要對該訊號燈變數做p,v操作,都必須使用mywait 和 mysignal ,mywait 和 myuwait不能對同乙個訊號等變數混合使用,否則系統會發生不可**的錯誤,我的經驗是,混合使用到一定時間後,訊號等變數的值會突然成乙個很大的隨機數。
訊號燈執行緒
這裡設定了乙個boolean的值,預設值是false 這裡面有二個執行緒,二個執行緒同時進入到tv 想象為容器 這個容器中 去拿資料!注意這裡有乙個boolean型別的燈!執行緒進去尋找方法!當boolean true的時候,生產表演了 voice!當boolean false的時候!就進去了!然後...
訊號燈與自旋鎖對比。
sem就是乙個睡眠鎖.如果有乙個任務試圖獲得乙個已被持有的訊號量時,訊號量會將其推入等待佇列,然後讓其睡眠。這時處理器獲得自由去執行其它 當持有訊號量的程序將訊號量釋放後,在等待佇列中的乙個任務將被喚醒,從而便可以獲得這個訊號量。訊號量一般在用程序上下文中.它是為了防止多程序同時訪問乙個共享資源 臨...
第10章 Posix訊號燈
三種訊號燈 說明 p v操作 互斥鎖 條件變數和訊號量之間的差別 include for o constants include for mode constants include sem t sem open const char name,int oflag sem t sem open co...