IPC筆記之System V訊號量

來源:互聯網
上載者:User
1、概述:System V訊號量用三個函數,semget,semop,semctl,分別是訊號量集的奪取,操作,控制。其操作對象是訊號量集合,semop操作的集合中,這些對象要麼全部成功,要麼全都不成功。

2、訊號量的銷毀,因為System V訊號量是核心持久性的,也就是說銷毀方式有兩種,要麼在進程中顯式銷毀,要麼只有當核心關閉時才銷毀。

3、核心中與訊號量有關的資料結構。

核心中維持一份全域的struct semid_ds數組,semid_ds是訊號量集合的結構。semget函數返回這個訊號量集合在數組中的小標。

struct semid_ds
{
    struct ipc_perm sem_perm;  //該訊號量集合的操作許可許可權
    struct sem *sem_base;    //該數組的元素是:該集合包含的訊號量的結構。
    ushort sem_nsems;   //sem_base數組的個數
    time_t sem_otime;  //最後一次成功修改該訊號量數組的時間。
    time_t sem_ctime;  //成功建立的時間
};

struct sem
{
    ushort semval;  //訊號量的當前值
    short sempid;  //最後一次返回該訊號量的進程的id號
    ushort semncnt; //等待semval大於當前值的進程的個數
    ushort semzcnt; //等待semval變成0的進程的個數
};

4、int shmget(key_t key, int nsems, int flag); 傳回值是訊號量標示符。

key: key_t是int型的,這個是一個整數,要保證核心唯一性。
nsems:該集合包含的訊號量的個數。
flag:建立的許可權, 可以使一些讀寫權限與:IPC_CREAT ( | IPC_EXCL )的按位或。

當該函數成功時,linux核心中的semval值為0,但是該值的初始化沒有可移植性(就是說不能保證所有系統都能初始化該值)

這個函數的作用:建立或者開啟訊號量集。

5、int semop(int semid, struct sembuf *opsptr, size_t nops);

semid:是semget返回的semid號。
nops:是數組opsptr的個數。
opsptr是操作結構的數組

struct sembuf
{
   short sem_num;   //訊號量在semid集合中的序號:0到nsems - 1;
   short sem_op;   //操作
   short sem_flag;   //0, IPC_NOWAIT, SEM_UNDO
};

其中,sem_op值如下:
a、如果sem_op大於0,表示sem_num訊號量所代表的資源的釋放,semval += sem_op;
b、如果sem_op小於0,表示sem_num訊號量所代表資源的分配,具體是:如果semval 大於等於 sem_op的絕對值,則semval -= sem_op絕對值;否則,阻塞知道條件滿足
c、如果sem_op等於0,表示直到semval 等於0時才返回。

6、int semctl(int semid, int semnum, int cmd, ../* union semun arg */);
其中semid是訊號量集合,semnum是訊號在集合中的序號,

union semun
{
    int val; /* cmd == SETVAL */
    struct semid_ds *buf /* cmd == IPC_SET或者 cmd == IPC_STAT */
    ushort *array; /* cmd == SETALL, 或 cmd = GETALL */
};

cmd取值如下:

GETVAL, SETVAL : semid集合中semnum訊號量當前的semval值
GETALL,SETALL :semid集合中所有訊號量的值。
IPC_RMID:刪除semid訊號量集
GETPID:返回最後成功操作該訊號的進程號。
IPC_STAT:返回semid集合中的struct semid_ds結構。

7、例子1:PV原語操作:

int sem_id = 0; /* semget的傳回值,全域 */
#define MUTEX 0 /* 用於返回臨界區的訊號量在集合中的序數 */
#define NUM_SEM 1 /* 集合中訊號量的個數 */
#define SEM_KEY 0x11223344 /*保證核心中的唯一性 */

void P(int sem_num)
{
    struct sembuf sem;
    sem.sem_num = MUTEX;
    sem.sem_op = -1;
    sem.sem_flg = 0;
    
    if( -1 == semop(sem_id, &sem, 1) )
    {
         /* 錯誤處理 */
    }
}


void V(int sem_num)
{
    struct sembuf sem;
    sem.sem_num = MUTEX;
    sem.sem_op = 1;
    sem.sem_flg = 0;
    
    if( -1 == semop(sem_id, &sem, 1) )
    {
         /* 錯誤處理 */
    }
}

主函數:

int main()
{
    ...
    int semid;
    ....
    semid = semget(SEM_KEY, 0, 0); /* panduan 判斷該型號量組是否已經存在 */
    if( -1 == semid )
    {
        semid = semget(SEM_KEY, NUM_SEM, IPC_CREAT | IPC_EXCL | 0666);
        if( -1 == semid)
        {
            /* 錯誤處理 */
        }
        else
        {
           semctl(sem_id, MUTEX, SETVAL, 1); /* 初始值為1。錯誤處理略 */
        }
    }

    ...
    P(MUTEX);
    /* 臨界區程式碼片段 */
    V(MUTEX);
    ...
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.