日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

进程间通信——信号量及ipcs/ipcrm 介绍

發(fā)布時間:2024/4/17 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 进程间通信——信号量及ipcs/ipcrm 介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.信號量描述

信號量是用來同步進(jìn)程的(即控制進(jìn)程的執(zhí)行),是一個特殊的變量,一般取正數(shù)值。它的值代表允許訪問的資源數(shù)目。獲取資源時,需要對信號量的值進(jìn)行原子減一,該操作被稱為 P 操作。當(dāng)信號量值為 0 時,代表沒有資源可用,P 操作會阻塞。釋放資源時,需要對信號量的值進(jìn)行原子加一,該操作被稱為 V操作。信號量主要用來同步進(jìn)程。信號量的值如果只取 0,1,將其稱為二值信號量。如果信號量的值大于 1,則稱之為計數(shù)信號量。
臨界資源:同一時刻,只允許被一個進(jìn)程或線程訪問的資源
臨界區(qū):訪問臨界資源的代碼段

2.信號量使用

2.1操作信號量的接口介紹:

#include <sys/sem.h> #include <sys/types.h> #include <sys/ipc.h> /* semget()創(chuàng)建或者獲取已存在的信號量 semget()成功返回信號量的 ID, 失敗返回-1 key:兩個進(jìn)程使用相同的 key 值,就可以使用同一個信號量 nsems:內(nèi)核維護(hù)的是一個信號量集,在新建信號量時,其指定信號量集中信號量的個數(shù) semflg 可選: IPC_CREAT IPC_EXCL */ int semget(key_t key, int nsems, int semflg);/* semop()對信號量進(jìn)行改變,做 P 操作或者 V 操作 semop()成功返回 0,失敗返回-1 nsops是信號量個數(shù) struct sembuf {unsigned short sem_num; //指定信號量集中的信號量下標(biāo)short sem_op; //其值為-1,代表 P 操作,其值為 1,代表 V 操作short sem_flg; //SEM_UNDO }; */ int semop( int semid, struct sembuf *sops, unsigned nsops);/* semctl()控制信號量 semctl()成功返回 0,失敗返回-1 cmd 選項: SETVAL //將val的值同步到信號量上IPC_RMID union semun//信號量下標(biāo) {int val;struct semid_ds *buf;unsigned short *array;struct seminfo *_buf; }; */ int semctl( int semid, int semnum, int cmd, ...);

2.2封裝信號量的接口:

sem.h 的代碼如下:

#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<assert.h> #include<sys/sem.h>union semu{int val};void sem_init();//創(chuàng)建并初始化,或者獲取已有的信號量id void sem_p();//p操作,信號量減一 void sem_v();//v操作,信號量加一 void sem_destroy();//銷毀信號量

sem.c代碼如下:

#include"sem.h"static int semid = -1;void sem_init() {semid = semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);if(semid == -1)//信號量已經(jīng)存在{semid = semget((key_t)1234,1,0600);}else//信號量不存在,信號量被創(chuàng)建,在這里初始化信號量{union semun a;a.val = 1;if(semctl(semid,0,SETVAL,a)==-1){perror("semctl error");}} }void sem_p() {struct sembuf buf;buf.sem_num = 0;buf.sem_op = -1;//Pbuf.sem_flg = SEM_UNDO;if(semop(semid,&buf,1)==-1){perror("semop P error");} }void sem_v() {struct sembuf buf;buf.sem_num = 0;buf.sem_op = 1;//Vbuf.sem_flg = SEM_UNDO;if(semop(semid,&buf,1)==-1){perror("semop V error");} }void sem_destroy() {if(semctl(semid,0,IPC_RMID) == -1){perror("semtcl del error");} }

記不住怎么封裝的也沒關(guān)系,一般我們使用時,都是封裝好的,我們只要知道怎么用信號量PV操作控制進(jìn)程就好。

2.3例題演示:

例題(1):進(jìn)程 a 和進(jìn)程 b 模擬訪問打印機(jī),進(jìn)程 a 輸出第一個字符‘a(chǎn)’表示開始使用打印機(jī),輸出第二個字符‘a(chǎn)’表示結(jié)束使用,b 進(jìn)程操作與 a 進(jìn)程相同。(由于打印機(jī)同一時刻只能被一個進(jìn)程使用,所以輸出結(jié)果不應(yīng)該出現(xiàn) abab),如圖所示:

a.c代碼如下:

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #include<unistd.h> #include"sem.h"int main() {sem_init();for(int i = 0; i < 5; i++){sem_p();printf("a start\t");sleep(3);printf("a end\n");sem_v();sleep(3);}sleep(10);sem_destroy();exit(0); }

a.c最后sleep(10)是為了使a程序最后結(jié)束,這樣可以在a程序里銷毀信號量。
b.c代碼:

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #include<unistd.h> #include"sem.h"int main() {sem_init();for(int i = 0; i < 5; i++){sem_p();printf("b start\t");sleep(3);printf("b end\n");sem_v();sleep(3);}exit(0); }

運(yùn)行結(jié)果:

可以發(fā)現(xiàn),由于打印機(jī)要求只有一個,所以a使用完打印機(jī),b或者a才能繼續(xù)使用打印機(jī),不可能a和b同時使用打印機(jī)的。

(2)例題2:有一個空間,要求A進(jìn)程先向里面寫數(shù)據(jù),B進(jìn)程再從里面讀數(shù)據(jù),然后A進(jìn)程再寫…
分析1:一個信號量情況如下:

一眼看去發(fā)現(xiàn)沒什么問題,但是仔細(xì)思考發(fā)現(xiàn)并沒有對A寫入數(shù)據(jù)進(jìn)行控制,A寫入數(shù)據(jù)不受信號量控制,A寫完仍可以寫。我們要求是A寫完之后,B讀完,A才可以再次寫入的。
所以不可行。
分析2:兩個信號量:
一個信號量限制A寫入,一個信號量限制B讀取
如下圖:

3.ipcs/ipcrm 介紹

ipcs 可以查看消息隊列、共享內(nèi)存、信號量的使用情況,使用 ipcrm 可以進(jìn)行刪除操作。
如果我們將a.c程序中的銷毀信號量的操作去掉,那么我們創(chuàng)建的信號量就沒有銷毀。a.c代碼如下。

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #include<unistd.h> #include"sem.h"int main() {sem_init();for(int i = 0; i < 5; i++){sem_p();printf("a start\t");sleep(3);printf("a end\n");sem_v();sleep(3);}exit(0); }

運(yùn)行完a和b程序后,由于程序里沒有對信號量進(jìn)行銷毀,所以我們創(chuàng)建的信號量仍然存在。可以用指令ipcs查看。
以下是運(yùn)行完a和b程序后用指令ipcs查看的信號量信息:

key值是16進(jìn)制,換成10進(jìn)制,就是我們程序中設(shè)置的key值1234。
可以用指令ipcrm + -s + semid指令銷毀信號量。

ipcrm -m是對共享內(nèi)存用的;
ipcrm -q是對消息隊列弄的;

總結(jié)

以上是生活随笔為你收集整理的进程间通信——信号量及ipcs/ipcrm 介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。