Linux C 信号量
文章目錄
- 1、信號(hào)量的概念
- 1.1、二元信號(hào)量
- 2、函數(shù)介紹
- 2.1、semget函數(shù)
- 2.2、semctl函數(shù)
- 2.3、semop函數(shù)
- 3、示例代碼
- 4、其他操作
1、信號(hào)量的概念
用于協(xié)調(diào)多個(gè)進(jìn)程(包括但不限于父子進(jìn)程)對(duì)共享數(shù)據(jù)對(duì)象的讀/寫。它不以傳送數(shù)據(jù)為目的,主要是用來保護(hù)共享資源,保證共享資源在一個(gè)時(shí)刻只有一個(gè)進(jìn)程獨(dú)享。
1.1、二元信號(hào)量
信號(hào)量是一個(gè)特殊的變量,只允許進(jìn)程對(duì)它進(jìn)行等待信號(hào)和發(fā)送信號(hào)操作。最簡單的信號(hào)量是取值0和1的二元信號(hào)量,這是信號(hào)量最常見的形式,1表示可以訪問,0表示加鎖
2、函數(shù)介紹
Linux中提供了一組函數(shù)用于操作信號(hào)量,程序中需要包含以下頭文件:
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h>2.1、semget函數(shù)
semget函數(shù)用來獲取或創(chuàng)建信號(hào)量
typedef unsigned int key_t int semget(key_t key, int nsems, int semflg); 參數(shù):key:是信號(hào)量的鍵值,是信號(hào)量在系統(tǒng)中的編號(hào)(一般用十六進(jìn)制表示)nsems:是創(chuàng)建信號(hào)量集中信號(hào)量的個(gè)數(shù),該參數(shù)只在創(chuàng)建信號(hào)量集時(shí)有效,這里固定填1。sem_flags:是一組標(biāo)志,如果希望信號(hào)量不存在時(shí)創(chuàng)建一個(gè)新的信號(hào)量,可以和值IPC_CREAT做按位或操作。如果沒有設(shè)置IPC_CREAT標(biāo)志并且信號(hào)量不存在,就會(huì)返錯(cuò)(errno的值為2,No such file or directory)返回值:成功:返回信號(hào)量集的標(biāo)識(shí)失敗:-1示例代碼: 1)獲取鍵值為0x5000的信號(hào)量,如果該信號(hào)量不存在,就創(chuàng)建它,代碼如下: int semid=semget(0x5000,1,0640|IPC_CREAT);2)獲取鍵值為0x5000的信號(hào)量,如果該信號(hào)量不存在,返回-1,errno的值被設(shè)置為2,代碼如下: int semid= semget(0x5000,1,0640);2.2、semctl函數(shù)
該函數(shù)用來控制信號(hào)量(常用于設(shè)置信號(hào)量的初始值和銷毀信號(hào)量
int semctl(int semid, int sem_num, int command, ...); 參數(shù):semid: semget函數(shù)返回值sem_num: 是信號(hào)量集數(shù)組上的下標(biāo),表示某一個(gè)信號(hào)量,填0cmd: 是對(duì)信號(hào)量操作的命令種類,常用的有以下兩個(gè):IPC_RMID:銷毀信號(hào)量,不需要第四個(gè)參數(shù);SETVAL:初始化信號(hào)量的值(信號(hào)量成功創(chuàng)建后,需要設(shè)置初始值),這個(gè)值由第四個(gè)參數(shù)決定。第四參數(shù)是一個(gè)自定義的共同體,如下: // 用于信號(hào)燈操作的共同體。union semun{int val;struct semid_ds *buf;unsigned short *arry;};示例: 1)銷毀信號(hào)量。semctl(semid,0,IPC_RMID); 2)初始化信號(hào)量的值為1,信號(hào)量可用。union semun sem_union;sem_union.val = 1;semctl(semid,0,SETVAL,sem_union);2.3、semop函數(shù)
該函數(shù)有兩個(gè)功能:1)等待信號(hào)量的值變?yōu)?,如果等待成功,立即把信號(hào)量的值置為0,這個(gè)過程也稱之為等待鎖;2)把信號(hào)量的值置為1,這個(gè)過程也稱之為釋放鎖。
int semop(int semid, struct sembuf *sops, unsigned nsops); 參數(shù):semid:semget函數(shù)返回的信號(hào)量標(biāo)識(shí)sops:是一個(gè)結(jié)構(gòu)體 struct sembuf {short sem_num; // 信號(hào)量集的個(gè)數(shù),單個(gè)信號(hào)量設(shè)置為0。short sem_op; // 信號(hào)量在本次操作中需要改變的數(shù)據(jù):-1-等待操作;1-發(fā)送操作。short sem_flg; // 把此標(biāo)志設(shè)置為SEM_UNDO,操作系統(tǒng)將跟蹤這個(gè)信號(hào)量。// 如果當(dāng)前進(jìn)程退出時(shí)沒有釋放信號(hào)量,操作系統(tǒng)將釋放信號(hào)量,避免資源被死鎖。 };nsops:是操作信號(hào)量的個(gè)數(shù),即sops結(jié)構(gòu)變量的個(gè)數(shù),設(shè)置它的為1(只對(duì)一個(gè)信號(hào)量的操作)示例: 1)等待信號(hào)量的值變?yōu)?span id="ze8trgl8bvbq" class="token number">1,如果等待成功,立即把信號(hào)量的值置為0; struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; semop(sem_id, &sem_b, 1);2)把信號(hào)量的值置為1。 struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; semop(sem_id, &sem_b, 1);3、示例代碼
這段代碼從嚴(yán)格來說是錯(cuò)誤的,因?yàn)槲覜]有加錯(cuò)誤處理,這樣子寫主要是為了理解,大家看一下加深理解就好,
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h>union semun // 用于信號(hào)量操作的共同體。 {int val;struct semid_ds *buf;unsigned short *arry; };int main() {int semid = semget(0x5000,1,0644|IPC_CREAT); // 創(chuàng)建或獲取信號(hào)量printf("semid:%d\n",semid); // 信號(hào)量idunion semun sem_union; // 設(shè)置信號(hào)量初始值sem_union.val = 1;semctl(semid,0,SETVAL,sem_union);int value = semctl(semid,0,GETVAL); // 獲取當(dāng)前信號(hào)量的值printf("value:%d\n",value);struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_op = -1;sem_b.sem_flg = SEM_UNDO; semop(semid,&sem_b,1); // 相當(dāng)于加鎖操作// 設(shè)置完之后信號(hào)量值就變成0了,標(biāo)識(shí)持有鎖int value1 = semctl(semid,0,GETVAL); // 獲取一下當(dāng)前信號(hào)量值,當(dāng)前值就是0printf("value1:%d\n",value1);sem_b.sem_num = 0; sem_b.sem_op = 1;sem_b.sem_flg = SEM_UNDO; semop(semid,&sem_b,1); // 釋放鎖操作// 設(shè)置完,信號(hào)量值為1int value2 = semctl(semid,0,GETVAL); // 獲取當(dāng)前信號(hào)量值,當(dāng)前值就是1printf("value1:%d\n",value2);return 0; }4、其他操作
1、用ipcs -s可以查看系統(tǒng)的信號(hào)量,內(nèi)容有鍵值(key),信號(hào)量編號(hào)(semid),創(chuàng)建者(owner),權(quán)限(perms),信號(hào)量數(shù)(nsems)。2、用ipcrm sem 信號(hào)量編號(hào),可以手工刪除信號(hào)量總結(jié)
以上是生活随笔為你收集整理的Linux C 信号量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言使用信号量(Linux)
- 下一篇: 手动 将exe加入到系统启动服务、卸载服