在Unix的System V中,Unix信號量通常被認為是對資源的訪問,因此資源可用則用正整數表示,當資源被全部占用,則為零。資源共享是UNIX多用戶系統的一個重要特征,Unix信號量(SEMAPHORE)則是防止兩個或多個進程同時訪問共享資源的一種機制。在Unix信號量機制實現之前,通常采用加鎖文件的方法,其算法描述如下:
⑴加鎖算法
- int lock(lockfile)
- /*返回值0代表成功,其它為失敗*/
- char *lockfile; /*加鎖文件名*/
- {
- intfd,ret=0;
- extern int errno;
- if((fd=open(lockfile,O_WRONLY|O_CREAT|O_EXCL,0666))==-1
- &&errno==EEXIST) ret=1;
- return(ret);
- }
⑵解鎖算法
- unlock(lockfile)
- char *lockfile; /*鎖文件名*/
- {
- unlink(lockfile);
- }
這種方法對訪問共享資源次數較少的進程是可行的,但對重載的使用則開銷太大了,況且一旦加鎖失敗則進程不知何時可以再試;當系統崩潰或重啟動時,加鎖文件可能會被忘掉了。
Dijkstra發表的Dekker算法給出了Unix信號量的一種實現,為整值對象定義了兩個了原語操作:P和V。其C描述如下:
- void P(sem)
- int *sem;
- {
- while (*sem<=0);
- (*sem)--;
- }
- void V(sem)
- int *sem;
- {
- (*sem)++;
- }
但上述算法不能在用戶空間編程,因為①sem指向的Unix信號量變量不能在進程間共享,它們有自己的數據段;②函數非原子執行,內核可在任何時候中斷一個進程;③若sem為0,進程並不釋放CPU。
所以Unix信號量必須由內核提供,它可在進程間共享數據,可執行原子操作(即一組操作要麼全部執行,要麼都不執行),可在一個進程阻塞時將CPU給另外一個進程。 這次關於Unix信號量的知識就先做個簡單的介紹。