semctl

系統調用semctl用來執行在信號量集上的控制操作。這和在訊息佇列中的系統調用msgctl是十分相似的。但這兩個系統調用的參數略有不同。

定義

semctl()系統調用:semctl();

原型:int semctl(int semid,int semnum,int cmd, /*union semun arg*/);

參數說明

返回值:如果成功,則為一個正數。

如果失敗,則為-1:errno=EACCES(許可權不夠)

EFAULT(arg指向的地址無效)

EIDRM(信號量集已經刪除)

EINVAL(信號量集不存在,或者semid無效)

EPERM(EUID沒有cmd的權利)

ERANGE(信號量值超出範圍)

因為信號量一般是作為一個信號量集使用的,而不是一個單獨的信號量。所以在信號量集的操作中,不但要知道IPC關鍵字值,也要知道信號量集中的具體的信號量。這兩個系統調用都使用了參數cmd,它用來指出要操作的具體命令。兩個系統調用中的最後一個參數也不一樣。在系統調用msgctl中,最後一個參數是指向核心中使用的數據結構的指針。我們使用此數據結構來取得有關訊息佇列的一些信息,以及設定或者改變佇列的存取許可權和使用者。但在信號量中支持額外的可選的命令,這樣就要求有一個更為複雜的數據結構。

系統調用semctl()的第一個參數是信號量集IPC標識符。第二個參數是操作信號在信號集中的編號,第一個信號的編號是0。

參數cmd中可以使用的命令如下:

·IPC_STAT讀取一個信號量集的數據結構semid_ds,並將其存儲在semun中的buf參數中。

·IPC_SET設定信號量集的數據結構semid_ds中的元素ipc_perm,其值取自semun中的buf參數。

·IPC_RMID將信號量集從記憶體中刪除。

·GETALL用於讀取信號量集中的所有信號量的值。

· GETNCNT返回正在等待資源的進程數目。

·GETPID返回最後一個執行semop操作的進程的PID。

·GETVAL返回信號量集中的一個單個的信號量的值。

·GETZCNT返回正在等待完全空閒的資源的進程數目。

·SETALL設定信號量集中的所有的信號量的值。

·SETVAL設定信號量集中的一個單獨的信號量的值。

參數arg代表一個semun的實例。semun是在linux/sem.h中定義的:

/*arg for semctl systemcalls.*/

union semun{

int val;/*value for SETVAL*/

struct semid_ds *buf;/*buffer for IPC_STAT&IPC_SET*/

ushort *array;/*array for GETALL&SETALL*/

struct seminfo *__buf;/*buffer for IPC_INFO*/

void *__pad;

val當執行SETVAL命令時使用。buf在IPC_STAT/IPC_SET命令中使用。代表了核心中使用的信號量的數據結構。array在使用GETALL/SETALL命令時使用的指針。

下面的程式返回信號量的值。當使用GETVAL命令時,調用中的最後一個參數被忽略:

intget_sem_val(intsid,intsemnum)

{

return(semctl(sid,semnum,GETVAL,0));

}

下面是一個實際套用的例子:

#defineMAX_PRINTERS5

printer_usage()

{

int x;

for(x=0;x<MAX_PRINTERS;x++)

printf("Printer%d:%d\n\r",x,get_sem_val(sid,x));

}

下面的程式可以用來初始化一個新的信號量值:

void init_semaphore(int sid,int semnum,int initval)

{

union semun semopts;

semopts.val=initval;

semctl(sid,semnum,SETVAL,semopts);

}

注意系統調用semctl中的最後一個參數是一個聯合類型的副本,而不是一個指向聯合類型的指針。

需要注意的是,對於semun聯合體,最好自己定義,否則GCC編譯器可能會報“semun大小未知”。

相關詞條

熱門詞條

聯絡我們