semctl() - Unix、Linux 系統呼叫 - 技術教學
Tutorials Point


  Unix 初學者指南
  Unix Shell 程式設計
  高階 Unix
  Unix 有用參考
  Unix 有用資源
  精選讀物

版權所有 © 2014 tutorialspoint



  首頁     參考     討論論壇     關於 TP  

semctl() - Unix、Linux 系統呼叫


previous next AddThis Social Bookmark Button

廣告

名稱

semctl - 訊號量控制操作

語法

#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/sem.h> 

int semctl(int semid, int semnum, int cmd, ...);

描述

semctl() 對由 semid 標識的訊號量集或該集合中的第 semnum 個訊號量執行由 cmd 指定的控制操作。(集合中的訊號量從 0 開始編號。)

此函式有三個或四個引數,具體取決於 cmd。當有四個引數時,第四個引數的型別為 union semun呼叫程式必須按如下方式定義此聯合體


union semun {
    int              val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                (Linux specific) */
};

semid_ds 資料結構在 <sys/sem.h> 中定義如下


struct semid_ds { struct ipc_perm sem_perm; /* Ownership and permissions time_t sem_otime; /* Last semop time */ time_t sem_ctime; /* Last change time */ unsigned short sem_nsems; /* No. of semaphores in set */ };

ipc_perm 結構在 <sys/ipc.h> 中定義如下(突出顯示的欄位可以使用 IPC_SET 設定)


struct ipc_perm {
    key_t key;            /* Key supplied to semget() */
    uid_t uid;            /* Effective UID of owner */
    gid_t gid;            /* Effective GID of owner */
    uid_t cuid;           /* Effective UID of creator */
    gid_t cgid;           /* Effective GID of creator */
    unsigned short mode;  /* Permissions */
    unsigned short seq;   /* Sequence number */
};

cmd 的有效值為

標籤描述
IPC_STAT 將與 semid 關聯的核心資料結構中的資訊複製到 arg.buf 指向的 semid_ds 結構中。semnum 引數被忽略。呼叫程序必須對訊號量集具有讀取許可權。
IPC_SET arg.buf 指向的 semid_ds 結構的一些成員的值寫入與該訊號量集關聯的核心資料結構,並更新其 sem_ctime 成員。更新結構的以下成員:sem_perm.uidsem_perm.gid 和(sem_perm.mode 的最低 9 位)。呼叫程序的有效 UID 必須與訊號量集的所有者(sem_perm.uid)或建立者(sem_perm.cuid)匹配,或者呼叫者必須具有特權。semnum 引數被忽略。
IPC_RMID 立即刪除訊號量集,喚醒所有在該集合上阻塞在 semop() 呼叫中的程序(並返回錯誤,並將 errno 設定為 EIDRM)。呼叫程序的有效使用者 ID 必須與訊號量集的建立者或所有者匹配,或者呼叫者必須具有特權。semnum 引數被忽略。
IPC_INFO(Linux 特定)
 將系統範圍內的訊號量限制和引數資訊返回到 arg.__buf 指向的結構中。如果定義了 _GNU_SOURCE 功能測試宏,則此結構的型別為 seminfo,在 <sys/sem.h> 中定義

struct seminfo { int semmap; /* # of entries in semaphore map; unused */ int semmni; /* Max. # of semaphore sets */ int semmns; /* Max. # of semaphores in all semaphore sets */ int semmnu; /* System-wide max. # of undo structures; unused */ int semmsl; /* Max. # of semaphores in a set */ int semopm; /* Max. # of operations for semop() */ int semume; /* Max. # of undo entries per process; unused */ int semusz; /* size of struct sem_undo */ int semvmx; /* Maximum semaphore value */ int semaem; /* Max. value that can be recorded for semaphore adjustment (SEM_UNDO) */ };

semmslsemmnssemopmsemmni 設定可以透過 /proc/sys/kernel/sem 進行更改;有關詳細資訊,請參見 proc(5)。
SEM_INFO(Linux 特定)
 返回一個 seminfo 結構,其中包含與 IPC_INFO 相同的資訊,但以下欄位返回有關訊號量消耗的系統資源的資訊:semusz 欄位返回系統上當前存在的訊號量集的數量;semaem 欄位返回系統上所有訊號量集中訊號量的總數。
SEM_STAT(Linux 特定)
 返回一個 semid_ds 結構,如 IPC_STAT 所示。但是,semid 引數不是訊號量識別符號,而是核心內部陣列中的索引,該陣列維護有關係統上所有訊號量集的資訊。
GETALL 將集合中所有訊號量的 semval(即當前值)返回到 arg.arraysemnum 引數被忽略。呼叫程序必須對訊號量集具有讀取許可權。
GETNCNT 系統呼叫返回集合中第 semnum 個訊號量的 semncnt 值(即等待此訊號量值增加的程序數)(即等待第 semnum 個訊號量的 semval 增加的程序數)。呼叫程序必須對訊號量集具有讀取許可權。
GETPID 系統呼叫返回集合中第 semnum 個訊號量的 sempid 值(即對第 semnum 個訊號量執行最後一次 semop() 呼叫的程序的 PID)。呼叫程序必須對訊號量集具有讀取許可權。
GETVAL 系統呼叫返回集合中第 semnum 個訊號量的 semval 值。呼叫程序必須對訊號量集具有讀取許可權。
GETZCNT 系統呼叫返回集合中第 semnum 個訊號量的 semzcnt 值(即等待此訊號量值變為零的程序數)(即等待第 semnum 個訊號量的 semval 變為 0 的程序數)。呼叫程序必須對訊號量集具有讀取許可權。
SETALL 使用 arg.array 設定集合中所有訊號量的 semval並更新與該集合關聯的 semid_ds 結構的 sem_ctime 成員。所有程序中已更改訊號量的撤消條目(請參見 semop(2))將被清除。如果訊號量值的更改允許其他程序中阻塞的 semop() 呼叫繼續執行,則喚醒這些程序。semnum 引數被忽略。呼叫程序必須對訊號量集具有更改(寫入)許可權。
SETVAL 將集合中第 semnum 個訊號量的 semval 值設定為 arg.val,並更新與該集合關聯的 semid_ds 結構的 sem_ctime 成員。所有程序中已更改訊號量的撤消條目將被清除。如果訊號量值的更改允許其他程序中阻塞的 semop() 呼叫繼續執行,則喚醒這些程序。呼叫程序必須對訊號量集具有更改許可權。

返回值

如果失敗,semctl() 將返回 -1,並使用 errno 指示錯誤。

否則,系統呼叫將返回一個非負值,具體取決於 cmd,如下所示

標籤描述
GETNCNT semncnt 的值。
GETPID sempid 的值。
GETVAL semval 的值。
GETZCNT semzcnt 的值。
IPC_INFO 核心內部陣列中最高使用條目的索引,該陣列記錄有關所有訊號量集的資訊。(此資訊可與重複的 SEM_STAT 操作一起使用,以獲取有關係統上所有訊號量集的資訊。)
SEM_INFO IPC_INFO 相同。
SEM_STAT 訊號量集的識別符號,其索引在 semid 中給出。
所有其他 cmd 值在成功時返回 0。

錯誤

如果失敗,errno 將設定為以下之一
標籤描述
EACCES cmd 引數具有 GETALLGETPIDGETVALGETNCNTGETZCNTIPC_STATSEM_STATSETALLSETVAL 中的一個值,並且呼叫程序對訊號量集沒有所需的許可權,並且沒有 CAP_IPC_OWNER 功能。
EFAULT arg.bufarg.array 指向的地址不可訪問。
EIDRM 訊號量集已刪除。
EINVAL cmdsemid 的值無效。或者:對於 SEM_STAT 操作,semid 中指定的索引值引用了當前未使用的陣列槽。
EPERM cmd 引數的值為 IPC_SETIPC_RMID,但呼叫程序的有效使用者 ID 不是訊號量集的建立者(在 sem_perm.cuid 中找到)或所有者(在 sem_perm.uid 中找到),並且程序沒有 CAP_SYS_ADMIN 功能。
ERANGE cmd 引數的值為 SETALLSETVAL,並且要設定為 semval 的值(對於集合中的某個訊號量)小於 0 或大於實現限制 SEMVMX

註釋

IPC_INFOSEM_STATSEM_INFO 操作由 ipcs(8) 程式用於提供有關已分配資源的資訊。將來可能會修改或移動到 /proc 檔案系統介面。

struct semid_ds 中的各個欄位在 Linux 2.2 下是短整型,在 Linux 2.4 下已成為長整型。為了利用這一點,在 glibc-2.1.91 或更高版本下重新編譯就足夠了。(核心透過 cmd 中的 IPC_64 標誌區分舊呼叫和新呼叫。)

在 glibc 的某些早期版本中,semun 聯合體在 <sys/sem.h> 中定義,但 POSIX.1-2001 要求呼叫者定義此聯合體。在 定義此聯合體的 glibc 版本上,宏 _SEM_SEMUN_UNDEFINED 在 <sys/sem.h> 中定義。

對訊號量集的以下系統限制會影響 semctl() 呼叫

標籤描述
SEMVMX semval 的最大值:依賴於實現(32767)。
為了獲得更好的可移植性,最好始終使用四個引數呼叫 semctl()。

在 Linux 下,semctl() 不是系統呼叫,而是透過系統呼叫 ipc(2) 實現的。

符合標準

SVr4、POSIX.1-2001。

參見



previous next Printer Friendly

廣告


  

廣告



廣告
© . All rights reserved.