進程間通信之信號he信號量

信號的篇幅較少,就把他和信號量放在一起了。先講講他們之間的區別:
1.信號:(signal)是一種處理異步事件的方式。信號時比較復雜的通信方式,用于通知接受進程有某種事件發生,除了用于進程外,還可以發送信號給進程本身。linux除了支持unix早期的信號語義函數,還支持語義符合posix.1標準的信號函數sigaction。

2.信號量:(Semaphore)進程間通信處理同步互斥的機制。是在多線程環境下使用的一種設施, 它負責協調各個線程, 以保證它們能夠正確、合理的使用公共資源。

信號:
使用信號要先知道有哪些信號,在Linux下有31個需要記住的通用信號,篇幅限制,這里就不贅述了。
signal:

#include <stdio.h>
#include <signal.h>// 信號處理函數
void handle(int signum)
{printf ("捕捉到一個信號 %d\n", signum);
}int main()
{signal(SIGINT, handle);signal(SIGTERM, handle);while (1);return 0;
}

kill:

#include <stdio.h>
#include <signal.h>int main()
{//while (1){kill (pid, sig);sleep(1);}return 0;
}

alarm:

#include <stdio.h>
#include <signal.h>// 信號處理函數
void handle(int signum)
{printf ("hello world\n");// 定時器重置alarm(2);
}int main()
{// 定時器是一次性的alarm(2);signal(SIGALRM, handle);while (1);return 0;
}

sigaction:

#include <stdio.h>
#include <signal.h>// 信號處理函數
void handle(int signum)
{printf ("hello world\n");// 定時器重置alarm(2);
}int main()
{// 定時器是一次性的alarm(2);struct sigaction act;act.sa_handler = handle;sigaction(SIGALRM, &act, NULL);while (1);return 0;
}

處理子進程的退出:

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>// 信號處理函數
void handle(int signum)
{while (waitpid (-1, NULL, WNOHANG) > 0){printf ("捕獲一個子進程\n");}printf ("111111\n");
}int main()
{signal (SIGCHLD, handle);int count = 10;while (count--){pid_t pid = fork(); switch (pid){case -1:perror ("fork");break;case 0: // 子進程printf ("我是子進程,我的Id 是%d\n", getpid());sleep(1);exit(0);default: // 父進程printf ("我是父進程,Id = %d\n", getpid());break;}}while (1);return 0;
}

信號量

一、什么是信號量

為了防止出現因多個程序同時訪問一個共享資源而引發的一系列問題,我們需要一種方法,它可以通過生成并使用令牌來授權,在任一時刻只能有一個執行線程訪問代碼的臨界區域。臨界區域是指執行數據更新的代碼需要獨占式地執行。而信號量就可以提供這樣的一種訪問機制,讓一個臨界區同一時間只有一個線程在訪問它,也就是說信號量是用來調協進程對共享資源的訪問的。

信號量是一個特殊的變量,程序對其訪問都是原子操作,且只允許對它進行等待(即P(信號變量))和發送(即V(信號變量))信息操作。最簡單的信號量是只能取0和1的變量,這也是信號量最常見的一種形式,叫做二進制信號量。而可以取多個正整數的信號量被稱為通用信號量。這里主要討論二進制信號量。

二、信號量的工作原理

由于信號量只能進行兩種操作等待和發送信號,即P(sv)和V(sv),他們的行為是這樣的:
P(sv):如果sv的值大于零,就給它減1;如果它的值為零,就掛起該進程的執行
V(sv):如果有其他進程因等待sv而被掛起,就讓它恢復運行,如果沒有進程因等待sv而掛起,就給它加1.

舉個例子,就是兩個進程共享信號量sv,一旦其中一個進程執行了P(sv)操作,它將得到信號量,并可以進入臨界區,使sv減1。而第二個進程將被阻止進入臨界區,因為當它試圖執行P(sv)時,sv為0,它會被掛起以等待第一個進程離開臨界區域并執行V(sv)釋放信號量,這時第二個進程就可以恢復執行。

三、Linux的信號量機制

Linux提供了一組精心設計的信號量接口來對信號進行操作,它們不只是針對二進制信號量,下面將會對這些函數進行介紹,但請注意,這些函數都是用來對成組的信號量值進行操作的。它們聲明在頭文件sys/sem.h中。
1、semget函數
它的作用是創建一個新信號量或取得一個已有信號量,原型為:

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

第一個參數key是整數值(唯一非零),不相關的進程可以通過它訪問一個信號量,它代表程序可能要使用的某個資源,程序對所有信號量的訪問都是間接的,程序先通過調用semget函數并提供一個鍵,再由系統生成一個相應的信號標識符(semget函數的返回值),只有semget函數才直接使用信號量鍵,所有其他的信號量函數使用由semget函數返回的信號量標識符。如果多個程序使用相同的key值,key將負責協調工作。

第二個參數num_sems指定需要的信號量數目,它的值幾乎總是1。

第三個參數sem_flags是一組標志,當想要當信號量不存在時創建一個新的信號量,可以和值IPC_CREAT做按位或操作。設置了IPC_CREAT標志后,即使給出的鍵是一個已有信號量的鍵,也不會產生錯誤。而IPC_CREAT | IPC_EXCL則可以創建一個新的,唯一的信號量,如果信號量已存在,返回一個錯誤。

semget函數成功返回一個相應信號標識符(非零),失敗返回-1.

2、semop函數
它的作用是改變信號量的值,原型為:

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

sem_id是由semget返回的信號量標識符,sembuf結構的定義如下:

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 semum結構,定義如下:

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

前兩個參數與前面一個函數中的一樣,command通常是下面兩個值中的其中一個
SETVAL:用來把信號量初始化為一個已知的值。p 這個值通過union semun中的val成員設置,其作用是在信號量第一次使用前對它進行設置。
IPC_RMID:用于刪除一個已經無需繼續使用的信號量標識符。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448453.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448453.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448453.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

開源當自強:我們不是“便宜貨”

之前人們爭相使用開源軟件&#xff0c;無非是因為它便宜、好用、易得&#xff0c;不過根據最新的開源軟件調查顯示&#xff0c;人們使用開源軟件最主要的原因還是看重它的高質量。 成本低是很過公司參與開源項目的最主要原因之一&#xff0c;而現在他們視開源是一條通往創新、省…

前端學習:Vue.js基本使用

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Vue教程文檔&#xff1a; https://cn.vuejs.org/v2/guide/ 定義 實例&#xff1a; new Vue() 掛載點: el 數據&#xff1a;data 模…

PWE

Obstacle Override Logic The obstacle override logic provides the possibility to override obstacle within a window movement by selective switching off the anti-trap functionality.轉載于:https://www.cnblogs.com/dannykong/p/11151813.html

進程間通信之消息隊列

一、什么是消息隊列 unix早期通信機制之一的信號能夠傳送的信息量有限&#xff0c;管道則只能傳送無格式的字節流&#xff0c;這無疑會給應用程序開發帶來不便。消息隊列&#xff08;也叫做報文隊列&#xff09;則克服了這些缺點。 消息隊列就是一個消息的鏈表。可以把消息看…

“ 愿我如星君如月,夜夜流光相皎潔 ...”

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 永遠相信愛情 ... 從一而終 ... --------------------------------------------------------------------------- 后記&#xff1a;2…

python內建函數和工廠函數的整理

內建函數參閱&#xff1a; https://www.cnblogs.com/pyyu/p/6702896.html 工廠函數&#xff1a; 本篇博文比較粗糙&#xff0c;后續會深入整理轉載于:https://www.cnblogs.com/qiang-upc/p/11155786.html

顯卡天梯圖:2014最新顯卡性能天梯圖

隨著電腦游戲的推廣&#xff0c;很多用戶都喜歡上了電腦網絡游戲&#xff0c;所以組裝電腦用戶在裝機的時候&#xff0c;會考慮電腦配置的游戲性能&#xff0c;要提高電腦配置游戲性能首要條件就是顯卡性能要強&#xff0c;如果顯卡性能不佳&#xff0c;那么其它方面性能再強&a…

進程間通信之分別用共享內存和信號量實現賣票

利用共享內存實現的賣票系統&#xff1a; 利用flag來保證同一時間只有一個程序使用內存&#xff0c;使用結束還原。 #include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <string.h> #include <…

shiro 的 @RequiresPermissions 注解使用

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 權限控制是shiro最核心的東西 Shiro權限聲明通常是使用以冒號分隔的表達式。一個權限表達式可以清晰的指定資源類型&#xff0c;允許的…

【顯卡天梯圖】2014年最新顯卡天梯圖 – 【迄今最全系列顯卡】

【顯卡天梯圖】2014年最新顯卡天梯圖 – 【迄今最全系列顯卡】 隨著電腦游戲的推廣&#xff0c;很多用戶都喜歡上了電腦網絡游戲&#xff0c;所以組裝電腦用戶在裝機的時候&#xff0c;會考慮電腦配置的游戲性能&#xff0c;要提高電腦配置游戲性能首要條件就是顯卡性能要強&am…

原理系列:Spark1.x 生態圈一覽

Spark生態圈&#xff0c;也就是BDAS&#xff08;伯克利數據分析棧&#xff09;&#xff0c;是伯克利APMLab實驗室精心打造的&#xff0c;力圖在算法&#xff08;Algorithms&#xff09;、機器&#xff08;Machines&#xff09;、人&#xff08;People&#xff09;之間通過大規模…

SpringMVC 注解 : @ModelAttribute

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 SpringMVC 注解 &#xff1a; ModelAttribute 的用法如上。 轉自&#xff1a;https://blog.csdn.net/lovesomnus/article/details/78873…

網絡編程項目(聊天室項目)

一、實現目標 一個在Linux下可以使用的聊天軟件&#xff0c;要求至少實現如下功能&#xff1a; 1. 采用Client/Server架構 2. Client A 登陸聊天服務器前&#xff0c;需要注冊自己的ID和密碼 3. 注冊成功后&#xff0c;Client A 就可以通過自己的ID和密碼登陸聊天服務器 4…

CPU天梯圖:2014年最新CPU性能天梯圖

用戶在組裝電腦的前期需要考慮怎么選擇適合自己的CPU&#xff0c;現在CPU性能強的比較貴&#xff0c;便宜的CPU性能又比較差&#xff0c;選擇性價比高并且適合自己的處理器還真是比較花心思。在2014年的時候&#xff0c;最主流熱門的AMD處理器是AMD A10-6800K&#xff0c;最新推…

解決: idea 修改 jsp 后,頁面刷新無效

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 idea 修改 jsp 后瀏覽器訪問無效。 解決&#xff1a;進入 idea 配置 修改部署方式&#xff1a; 修改 更新文件方式&#xff1a; OK了。

Python中的getpass模塊

getpass模塊用于輸入密碼時&#xff0c;隱藏密碼字符 代碼 import getpass name input("請輸入你的名字&#xff1a;") passwd getpass.getpass("請輸入你的密碼&#xff1a;")print (name,passwd)   首先我們要import引入getpass模塊&#xff0c;然后…

C++之命名空間

為什么要使用命名空間&#xff1f; 一個中大型軟件往往由多名程序員共同開發&#xff0c;會使用大量的變量和函數&#xff0c;不可避免地會出現變量或函數的命名沖突。當所有人的代碼都測試通過&#xff0c;沒有問題時&#xff0c;將它們結合到一起就有可能會出現命名沖突。 …

如何做到每天寫代碼?

摘要&#xff1a;總有一大堆事情沒有做完&#xff0c;沒有時間和精力為業余項目寫代碼&#xff1f;不要著急&#xff0c;看看可汗學院計算機科學院院長John Resig怎么說。本文將教你如何保證在每天都能有時間給業余項目寫代碼。 你是否曾為業余項目沒有進展而惆悵過&#xff1f…

Vue 實現前后端分離項目

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Vue實現前后端分離項目的初體驗 經過之前學習的Vue的知識&#xff1a; vue基本指令vue組件vue-resourcevue路由 其實我們已經可以開始…

C++對C的一些加強和變化

實用性加強&#xff1a; int main() {// C語言中的變量都必須在作用域開始的位置定義&#xff01;&#xff01;// C中更強調語言的“實用性”&#xff0c;所有的變量都可以在需要使用時再定義。for (int i 0; i < 10; i){std::cout << i << std::endl;}return…