1. 程式人生 > >Linux程序間通訊:訊號量 semget()、semop()、semctl()

Linux程序間通訊:訊號量 semget()、semop()、semctl()

這篇文章將講述別一種程序間通訊的機制——訊號量。注意請不要把它與之前所說的訊號混淆起來,訊號與訊號量是不同的兩種事物。有關訊號的更多內容,可以閱讀我的另一篇文章:Linux程序間通訊 -- 訊號。下面就進入訊號量的講解。

一、什麼是訊號量

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

訊號量是一個特殊的變數,程式對其訪問都是原子操作,且只允許對它進行等待(即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結構的定義如下:

1 2 3 4 5 6 7 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結構,定義如下:

1 2 3 4 5 union semun { int val; struct semid_ds *buf; unsigned short *arry; };

前兩個引數與前面一個函式中的一樣,command通常是下面兩個值中的其中一個

SETVAL:用來把訊號量初始化為一個已知的值。p 這個值通過union semun中的val成員設定,其作用是在訊號量第一次使用前對它進行設定。

IPC_RMID:用於刪除一個已經無需繼續使用的訊號量識別符號。

四、程序使用訊號量通訊

下面使用一個例子來說明程序間如何使用訊號量來進行通訊,這個例子是兩個相同的程式同時向螢幕輸出資料,我們可以看到如何使用訊號量來使兩個程序協調工作,使同一時間只有一個程序可以向螢幕輸出資料。注意,如果程式是第一次被呼叫(為了區分,第一次呼叫程式時帶一個要輸出到螢幕中的字元作為一個引數),則需要呼叫set_semvalue()函式初始化訊號並將message字元設定為傳遞給程式的引數的第一個字元,同時第一個啟動的程序還負責訊號量的刪除工作。如果不刪除訊號量,它將繼續在系統中存在,即使程式已經退出,它可能在你下次執行此程式時引發問題,而且訊號量是一種有限的資源。

在main函式中呼叫semget()來建立一個訊號量,該函式將返回一個訊號量識別符號,保存於全域性變數sem_id中,然後以後的函式就使用這個識別符號來訪問訊號量。

原始檔為seml.c,程式碼如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

相關推薦

Linux程序通訊訊號 semget()semop()semctl()

這篇文章將講述別一種程序間通訊的機制——訊號量。注意請不要把它與之前所說的訊號混淆起來,訊號與訊號量是不同的兩種事物。有關訊號的更多內容,可以閱讀我的另一篇文章:Linux程序間通訊 -- 訊號。下面就進入訊號量的講解。 一、什麼是訊號量 為了防止出現

Linux程序通訊訊號(semaphore)訊息佇列(Message Queue)和共享記憶體(Share Memory)

System V 程序通訊方式:訊號量(semaphore)、訊息佇列(Message Queue)和共享記憶體(Share Memory) 訊號量 訊號量(semaphore)實際是一個整數,它的值由多個程序進行測試(test)和設定(set)。就每個程序所關心的測試和

Linux程序通訊——使用訊號

這篇文章將講述別一種程序間通訊的機制——訊號量。注意請不要把它與之前所說的訊號混淆起來,訊號與訊號量是不同的兩種事物。有關訊號的更多內容,可以閱讀我的另一篇文章:Linux程序間通訊——使用訊號。下面就進入訊號量的講解。 一、什麼是訊號量 為了防止出現因多個程式同時訪問一

linux程序通訊訊號(semaphore)

==================================================== 訊號量(semaphore)簡介 當我們在多使用者系統,多程序系統,或是兩者混合的系統中使用執行緒操作編寫程式時,我們經常會發現我們有段臨界程式碼,在此處我們需要

linux下c程式設計之訊號semgetsemopsemctl函式

訊號量 今天去參加北京市的植樹志願者活動啦!早上起來的挺早的,6:10就被傑子給叫起來啦,帶著對春天的嚮往,我們坐著不花錢的大巴去做為市領導服務去啦!發了一個小紅帽還有一個紅色的制服。 唉。。。說好

Linux 多工程式設計——程序通訊訊號中斷處理

什麼是訊號? 訊號是 Linux 程序間通訊的最古老的方式。訊號是軟體中斷,它是在軟體層次上對中斷機制的一種模擬,是一種非同步通訊的方式 。訊號可以導致一個正在執行的程序被另一個正在執行的非同步程序中斷,轉而處理某一個突發事件。 “中斷”在我們生活中經常遇到,譬如,我正在房間裡打遊戲,

Linux系統程式設計——程序通訊訊號中斷處理

什麼是訊號? 訊號是 Linux 程序間通訊的最古老的方式。訊號是軟體中斷,它是在軟體層次上對中斷機制的一種模擬,是一種非同步通訊的方式 。訊號可以導致一個正在執行的程序被另一個正在執行的非同步程序中斷,轉而處理某一個突發事件。 “中斷”在我們生活中經常遇到,譬如,我正在

程序通訊訊號

執行以下程式碼,在終端運用kill命令向該程序傳送訊號 ,測試哪個中斷不能被自己所寫的函式接管 #include <stdio.h> #include <signal.h> #include <unistd.h> void handler (int num) {

Linux程序通訊訊號通訊

訊號通訊是Linux程序間通訊的一種方式。 1.什麼是訊號? 訊號是系統響應某些條件而產生的一個事件,接收到該訊號的程序會相應地採取一些措施。例如我們在windows系統中想強制結束一個程式我們需要用到的是工作管理員,而在Linux中,我們是通過訊號來實現的,執

linux 程序通訊訊號

Linux訊號(signal) 機制分析 轉載至:https://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html 【摘要】本文分析了Linux核心對於訊號的實現機制和應

程序通訊方式——訊號(Semaphore)

1.訊號量 訊號量本質上是一個計數器(不設定全域性變數是因為程序間是相互獨立的,而這不一定能看到,看到也不能保證++引用計數為原子操作),用於多程序對共享資料物件的讀取,它和管道有所不同,它不以傳送資料為主要目的,它主要是用來保護共享資源(訊號量也屬於臨界資源

程序通訊訊號

何為訊號量 訊號量的本質是一種資料操作鎖,它本身不具有資料交換的功能,而是通過控制其他的通訊資源(檔案,外部裝置)來實現程序間通訊,它本身只是一種外部資源的標識。訊號量在此過程中負責資料操作的互斥、同步等功能。 對訊號量的操作 當請求一個使用訊號量來表示的資源時,程序需要

程序通訊之——訊號(一)(system V)

system v訊號量又被稱為system v訊號量集。它的本質就是一個計數器,用來為多個程序共享的資料結構提供受控訪問。訊號量支援的操作有:使用最廣泛的訊號量為二元訊號量,它控制單個資源,對於這種訊號量而言,它只有兩種合法值: 0 和 1 ,對應一個可用的資源。若當前有資源

Linux 程序通訊(四)訊號

1 訊號量概述 訊號量和其他IPC不同,並沒有在程序之間傳送資料,訊號量用於多程序在存取共享資源時的同步控制就像交通路口的紅路燈一樣,當訊號量大於0,表示綠燈允許通過,當訊號量等於0,表示紅燈,必須停下來等待綠燈才能通過。 程序間的互斥關係與同步關係存在的根源在於臨界資

Linux程序通訊(四)訊號

雖然本文是記錄使用訊號量保證程序的同步與互斥的,但是其實也可以看做是程序之間的通訊問題,為了與前面的保持一致,所以還是叫做 Linux程序間通訊了 (強迫症...) 訊號量 基本概念 程序間通訊的方式有管道、訊息佇列、共享記憶體這些都是程序間的資訊通訊,而訊號量可以理解為程序使用的臨界資源的狀態說明,訊

Linux程序通訊--訊號,管道,訊息佇列,訊號,共享記憶體,socket

Linux 傳統的程序間通訊有很多,如各類管道、訊息佇列、記憶體共享、訊號量等等。但它們都無法介於核心態與使用者態使用,原因如表 通訊方法 無法介於核心態與使用者態的原因 管道(不包括命名管道) 侷限於父子程序間的通訊。 訊息佇列 在硬、軟中斷中無法無阻塞地接收資料。 訊號量 無法介於核

Linux程序通訊(IPC)程式設計實踐(十)System V訊號---PV操作經典題目

//P原語     //P(semaphore *S)     wait(semaphore *S)       {           -- S->value;           if (S->value < 0)           {   

linux程序通訊訊號例項(C語言)

 這篇發的很糾結,這不是我原創的程式碼,是同學寫的,我只是想在這記錄下來,以後沒事可以看看,寫轉載嘛,又沒有轉載的來源,翻譯就更扯了,勉強寫個原創,其實不是我原創啦。 ( ̄▽ ̄)" 有興趣可以看下,這是關於linux中的訊號量的使用的一篇文章。我加了一些註釋。 題目是:寫一個程式,該程式建立兩個程序,分

Linux程序通訊--共享記憶體與訊號

1. 建立共享記憶體,shmget() shmget(建立或開啟共享記憶體) 表頭檔案#include <sys/ipc.h>#include <sys/shm.h> 函式定義  int shmget(key_t key, size_t size, int shmflg); 函式說明k

linux程序通訊-訊號

引入訊號量之前,先介紹幾個概念: 1.臨界資源:同一時刻只允許一個程序或執行緒訪問的資源。(有時候是有限個程序或執行緒訪問),就比如一支筆一次只能是一個人使用。 這裡的臨界資源在c語言或c++中的表