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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

进程间通信之信号量

發布時間:2025/5/22 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 进程间通信之信号量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在學習進程間通信時,信號量可能是我們會感到有點頭痛的地方。事實上,我們知道了信號量的作用再去理解信號量就會容易很多。先將信號量(System V信號量)介紹如下:
1)為什么需要使用信號量?
因為我們的系統資源是有限的,但是系統是多任務的,所以存在多進程、多線程,可能同時需要對某一個資源進行訪問,用來保證資源的有序訪問。
否則會產生不可預計的結果。
2)信號量是什么東西?
信號量是一個計數值,這個值表示當前可用的資源數,這個值也是可用是一個負數,負數的話,表示的是等待的進程數量。還有一個指針,這個指針指向等待該信號量的進程
P操作,減一操作。
V操作,加一操作。
操作屬于原子操作,是不可被打斷一種操作,一定要等待這個操作的完成。要包含的代碼要盡量段,而且不要有循環。

3)如何使用信號量?(1)、產生一個key值。SYNOPSIS#include <sys/types.h>#include <sys/ipc.h>key_t ftok(const char *pathname, int proj_id);pathname (which must refer to an existing, accessible file) 這個路徑必須是一個存在的、可訪問的的文件proj_id (which must be nonzero) to generate a key_t 必須是一個非零的數字,然后通過這個函數就會產生一個key_t類型的標示符。返回值:成功就會返回 對應的key值,錯誤返回-1,并且可以把對應的錯誤碼打印出來看一下是什么錯誤。(2)、根據這個key值,去創建一個信號量。不同進程就可以根據這個信號量的ID去找到這個信號量,然后操作它。SYNOPSIS#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>int semget(key_t key, int nsems, int semflg);key: 就是我們第一步通過ftok產生的key值。nsems:信號量的個數。semflg:創建 IPC_CREAT | 權限位 例如: IPC_CREAT | 0664 (3)、要對這個信號量,進行初始化。SYNOPSIS#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>int semctl(int semid, int semnum, int cmd, ...);semid:是創建的信號量的IDsemnum:表示是對第幾個信號量來進行設置。cmd:SETVAL 設置信號量的初始值。第四個參數,取決于第三個參數,如果有第四個參數的話,它是一個聯合體,這個聯合體是這樣定義的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) */};(4)、調用這個信號量去保護臨界資源。調用P操作,用完之后,調用V操作。SYNOPSIS#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>int semop(int semid, struct sembuf *sops, unsigned nsops);semid:這個信號量的IDstruct sembuf, containing the following members:unsigned short sem_num; /* semaphore number操作第幾個信號量 */short sem_op; /* semaphore operation P還是V操作,如果是互斥式的信號量,P操作,這個就等于-1,如果是v操作就等于1 */short sem_flg; /* operation flags SEM_UNDO */成功返回0,失敗返回-1;

具體代碼如下:

#include<stdlib.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> #include <stdio.h>union semun {int val;struct semid_df*buf;unsigned short *array; }; int sem_p(int semid) {struct sembuf sbuf;sbuf.sem_num=0; //表示對第幾個信號量作操作sbuf.sem_op=-1;//p操作,為減一操作sbuf.sem_flg=SEM_UNDO; //默認使用這個標志位if((semop(semid,&sbuf,1))==-1) //去設置這個信號量{perror("p op fail");return -1;}return 0; } int sem_v(int semid) {struct sembuf sbuf;sbuf.sem_num=0;sbuf.sem_op=1;sbuf.sem_flg=SEM_UNDO;if((semop(semid,&sbuf,1))==-1){perror("p op fail");return -1;}return 0; } int main() {key_t key;int semid,ret;pid_t pid;union semun tmp;key =ftok("/home/gec",2);//產生一個key值,用來創建一個信號量printf("key=%d",key);if(key<0){perror("ftok fail");exit(1);}//創建這個信號量 1代表信號量的個數,返回信號量的IDsemid = semget(key,1,IPC_CREAT|0777);if(semid<0){perror("semget fail");exit(-1);}tmp.val=0;//初始化信號量的初始值為0,所以下面的操作就要先用v操作來釋放這個信號量ret=semctl(semid,0,SETVAL,tmp);if(ret<0){perror("semctl fail");exit(-1);}pid = fork();if(pid < 0){perror("fork fail");exit(-1);}if(pid == 0){//因為信號量的初始值為0,所以不用p操作,如果這里也用p操作大家都會鎖死 // sem_p(semid);sleep(3);printf("Child pid :%d\n",getpid());sem_v(semid);//完了之后用V操作,回覆信號量初始值為1}else if(pid > 0){//父進程等待信號量的恢復,恢復了之后,執行P操作,然后往下執行sem_p(semid);printf("Parent pid:%d\n",getpid());//用完之后,執行V操作,恢復信號量sem_v(semid);//用完之后,把這個信號量刪除 semctl(semid,0,IPC_RMID,tmp);}return 0; }

總結

以上是生活随笔為你收集整理的进程间通信之信号量的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。