日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

UNIX多用戶系統(tǒng)下信號量操作詳解

【UNIX多用戶系統(tǒng)下信號量操作詳解】
資源共享是Unix多用戶系統(tǒng)的一個重要特征,信號量(SEMAPHORE)則是防止兩個或多個進(jìn)程同時訪問共享資源的一種機(jī)制 。在信號量機(jī)制實現(xiàn)之前,通常采用加鎖文件的方法,其算法描述如下:

⑴加鎖算法

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);
}

這種方法對訪問共享資源次數(shù)較少的進(jìn)程是可行的,但對重載的使用則開銷太大了,況且一旦加鎖失敗則進(jìn)程不知何時可以再試;當(dāng)系統(tǒng)崩潰或重啟動時,加鎖文件可能會被忘掉了 。

Dijkstra發(fā)表的Dekker算法給出了信號量的一種實現(xiàn),為整值對象定義了兩個了原語操作:P和V 。其C描述如下:

void P(sem)
int *sem;
{
while (*sem<=0);
(*sem)--;
}

void V(sem)
int *sem;
{
(*sem);
}

但上述算法不能在用戶空間編程,因為①sem指向的信號量變量不能在進(jìn)程間共享,它們有自己的數(shù)據(jù)段;②函數(shù)非原子執(zhí)行,內(nèi)核可在任何時候中斷一個進(jìn)程;③若sem為0,進(jìn)程并不釋放CPU 。

所以信號量必須由內(nèi)核提供,它可在進(jìn)程間共享數(shù)據(jù),可執(zhí)行原子操作(即一組操作要么全部執(zhí)行,要么都不執(zhí)行),可在一個進(jìn)程阻塞時將CPU給另外一個進(jìn)程 。

UNIXSYSTEMV以一個長整數(shù)的鍵值作為信號量集合的唯一標(biāo)識,信號量通常由下列元素組成:

①信號量的值,

②操作該信號量的最后一個進(jìn)程的進(jìn)程標(biāo)識,

③等待增加該信號量的值的進(jìn)程數(shù),

④等待該信號量的值為0的進(jìn)程數(shù) 。

與之有關(guān)的系統(tǒng)調(diào)用如下:

#include
#include
#include

int semget(key,count,flags)
/*獲取信號量集合的標(biāo)識符*/
key_tkey; /*信號量集合的鍵*/
intcount; /*信號量集合中元素個數(shù)*/
intflags; /*任選參數(shù)*/
/*返回信號量集合標(biāo)識符,若出錯則返回-1*/

int semop(sid,ops,nops) /*信號量操作*/
int sid; /*信號量集合標(biāo)識符*/
struct sembuf *ops; /*信號量操作結(jié)構(gòu)的指針*/
intnops; /*信號量操作結(jié)構(gòu)的個數(shù)*/
/*返回運(yùn)算完成前該組信號量中最后一個被運(yùn)算的信號量的
值,若出錯則返回-1*/

int semctl(sid,semnum,cmd,arg)
/*控制信號量操作*/
intsid; /*信號量集合標(biāo)識符*/
intsemnum; /*信號量元素編號*/
intcmd; /*控制命令*/
union semun{
intval;
struct semid_ds *buf;
ushort*array;} arg; /*命令參數(shù)*/


系統(tǒng)調(diào)用semget用來把信號量集合的鍵值譯成代表信號量集合的標(biāo)識符,該集合中有count個元素,其存取權(quán)限定義與文件相同,由flags定義 。若flags的IPC_CREAT位被置位,則當(dāng)該集合不存在時系統(tǒng)就創(chuàng)建之 。因此各進(jìn)程可都用置IPC_CREAT位的flags參數(shù)來獲取信號量集合的標(biāo)識符,不需要由某一進(jìn)程事先創(chuàng)建 。若flags為IPC_PRIDVATE則不管同鍵值的信號量集合是否存在系統(tǒng)都建立之,并返回下一個可用的標(biāo)識符 。

系統(tǒng)調(diào)用semctl在一組信號量上做各種控制操作,諸如信號量集合的初始化、刪除和狀態(tài)查詢等 。常用的操作及相關(guān)的命令格式如下:

①取消信號量集合

int semctl(sid,count,IPC_RMID,0)
int sid; /*信號量集合標(biāo)識符*/
int count; /*信號量集合中元素個數(shù)*/

②設(shè)置信號量集合的初值(初始化)

信號量集合剛建立時,各信號量的初值不確定,需要設(shè)定初值 。初值的設(shè)定可用SETALL或SETVAL命令 。若用SETALL命令,其格式為:

int semctl(sid,count,SETALL,arg)

推薦閱讀