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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux信号量详解

發布時間:2023/12/31 linux 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux信号量详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Linux信號量詳解

1.什么是信號量
信號量是一種特殊的變量,訪問具有原子性。
只允許對它進行兩個操作:
1)等待信號量
當信號量值為0時,程序等待;當信號量值大于0時,信號量減1,程序繼續運行。
2)發送信號量
將信號量值加1。

我們使用信號量,來解決進程或線程間共享資源引發的同步問題。

2.Linux中信號量的使用
Linux提供了一組信號量API,聲明在頭文件sys/sem.h中。
1)semget函數:新建信號量

int semget(key_t key,int num_sems,int sem_flags);

key:信號量鍵值,可以理解為信號量的唯一性標記。
num_sems:信號量的數目,一般為1
sem_flags:有兩個值,IPC_CREATE和IPC_EXCL,
IPC_CREATE表示若信號量已存在,返回該信號量標識符。
IPC_EXCL表示若信號量已存在,返回錯誤。

返回值:相應的信號量標識符,失敗返回-1

2)semop函數:修改信號量的值

int semop(int sem_id,struct sembuf *sem_opa,size_t num_sem_ops);

sem_id:信號量標識符
sem_opa:結構如下

struct sembuf{ short sem_num;//除非使用一組信號量,否則它為0 short sem_op;//信號量在一次操作中需要改變的數據,通常是兩個數,一個是-1,即P(等待)操作, //一個是+1,即V(發送信號)操作。 short sem_flg;//通常為SEM_UNDO,使操作系統跟蹤信號, //并在進程沒有釋放該信號量而終止時,操作系統釋放信號量 };

3)semctl函數:用于信號量的初始化和刪除

int semctl(int sem_id,int sem_num,int command,[union semun sem_union]);

command:有兩個值SETVAL,IPC_RMID,分別表示初始化和刪除信號量。
sem_union:可選參數,結構如下:

union semun{ int val; struct semid_ds *buf; unsigned short *arry; };

一般用到的是val,表示要傳給信號量的初始值。

3.Linux信號量使用示例
下例中,我們寫了一個程序,程序中有一個char類型的字符,char message='x'
然后同時運行這個程序的兩個實例。
第一個實例,帶一個參數,將參數的第一個字符賦給message,比如為'0'
第二個實例,使用默認message值'x'
我們的目的是,使用信號量,循環執行這兩個實例,
我們可以看到執行結果應該是'x0x0x0x0x0x0'

#include<stdio.h> #include<stdlib.h> #include<sys/sem.h> union semun {int val;struct semid_ds *buf;unsigned short *array; }; int sem_id; int set_semvalue() {union semun sem_union; sem_union.val = 1;if(semctl(sem_id,0,SETVAL,sem_union)==-1)return 0;return 1; } int semaphore_p() {struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_op = -1;sem_b.sem_flg = SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){fprintf(stderr,"semaphore_p failed\n");return 0;}return 1; } int semaphore_v() {struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_op = 1;sem_b.sem_flg = SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){fprintf(stderr,"semaphore_v failed\n");return 0;}return 1; } void del_semvalue() {//刪除信號量 union semun sem_union;if(semctl(sem_id,0,IPC_RMID,sem_union)==-1)fprintf(stderr,"Failed to delete semaphore\n"); } int main(int argc,char *argv[]) {char message = 'x';//創建信號量sem_id = semget((key_t)1234,1,0666|IPC_CREAT);if(argc>1){//初始化信號量if(!set_semvalue()){fprintf(stderr,"init failed\n");exit(EXIT_FAILURE);}//參數的第一個字符賦給messagemessage = argv[1][0];}int i=0;for(i=0;i<5;i++){//等待信號量if(!semaphore_p())exit(EXIT_FAILURE);printf("%c",message);fflush(stdout);sleep(1);//發送信號量if(!semaphore_v())exit(EXIT_FAILURE);sleep(1);}printf("\n%d-finished\n",getpid());if(argc>1){//退出前刪除信號量 del_semvalue();}exit(EXIT_SUCCESS); }

輸出結果:

總結

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

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