Linux程序間通訊之訊號量

2021-06-21 15:34:27 字數 2906 閱讀 1130

眾所周知,每個程序使用的資料是是它獨有的,即使之前沒有,它也會在自己的記憶體區域拷貝乙個(這裡不考慮共享記憶體機制)。

如果程序間需要通訊,有共享資源時,訊號,管道,訊息佇列,訊號量,共享記憶體,

這幾種技術都可以幫我們。這裡先介紹訊號量

訊號量定義:

為了防止出現因多個程式同時訪問乙個共享資源而引發的一些問題,我們需要任一時刻只有乙個執行執行緒訪問**的臨界區域。而訊號量就可以提供這樣的一種訪問機制,讓乙個臨界區同一時間只有乙個執行緒在訪問它。

訊號量是乙個特殊的變數,程式對其訪問都是原子操作,且只允許對它進行等待(即p(訊號變數))和傳送(即v(訊號變數))資訊操作。

這裡二進位制訊號量是最常見的訊號量,本文也重點討論二進位制訊號量

工作原理:

訊號量只能進行兩種操作(等待和傳送訊號),即pv操作

p:如果訊號量變數》=0,就將其減-,如果值為0,就掛起該程序的執行

v:如果有其他程序因等待訊號量變數而被掛起,就將其恢復,如果沒有,就將變數加-;

通俗一點的說就是:如果乙個程序執行p操作進入了臨界區,變數變為0,而另乙個程序執行p的時候發現變數為0,將被掛起。而第乙個程序執行完了後執行v操作時發現第二個程序在等待該變數,就將其恢復,這時變數沒變值。

函式:

1:semget函式:建立乙個新訊號量或者取消乙個已有訊號量

intsemget(key_t key, 

intnum_sems, 

intsem_flags);  

第乙個引數key是整數值(唯一非零),不相關的程序可以通過它訪問乙個訊號量,它代表程式可能要使用的某個資源,程式對所有訊號量的訪問都是間接的,程式先通過呼叫semget函式並提供乙個鍵,再由系統生成乙個相應的訊號識別符號(semget函式的返回值),只有semget函式才直接使用訊號量鍵,所有其他的訊號量函式使用由semget函式返回的訊號量識別符號。

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

第三個引數sem_flags是一組標誌,當想要當訊號量不存在時建立乙個新的訊號量,可以和值ipc_creat做按位或操作。設定了ipc_creat標誌後,即使給出的鍵是乙個已有訊號量的鍵,也不會產生錯誤。而ipc_creat | ipc_excl則可以建立乙個新的,唯一的訊號量,如果訊號量已存在,返回乙個錯誤。

semget函式成功返回乙個相應訊號識別符號(非零),失敗返回-1.

2、semop函式:改變訊號量的值

intsemop(

intsem_id, 

struct

sembuf *sem_opa, 

size_t

num_sem_ops);

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

struct sembuf;
3、semctl函式: 直接控制訊號量資訊

intsemctl(

intsem_id, 

intsem_num, 

intcommand, ...); 

如果有第四個引數,它通常是乙個union semum結構,定義如下:

union semun;
這裡舉個程序使用訊號量來通訊的例子:  例子是兩個相同的程式同時向螢幕輸出字元,這個例子要同一時間只有乙個程序輸出字元

#include #include #include #include #include #include #include #include union semun

;static int sem_id = 0;

static int set_semvalue();

static void del_semvalue();

static int semaphore_p();

static int semaphore_v();

int main(int argc, char *argv)

//設定要輸出到螢幕中的資訊,即其引數的第乙個字元

message = argv[1][0];

sleep(2);

} for(i = 0; i < 10; ++i)

sleep(10);

printf("\n%d - finished\n", getpid());

if(argc > 1)

exit(exit_success);

}static int set_semvalue()

static void del_semvalue()

static int semaphore_p()

return 1;

}static int semaphore_v()

return 1;

}

結果如下:

可以發現x和 我輸入的第乙個引數0都是成對的列印的,這是因為p操作進入臨界區後,另乙個程序無法進入,只有當前程序再次列印乙個字元並執行v操作後,另乙個程序才能夠進去。

為了驗證訊號量的作用,這裡舉個不用訊號量的例子:

#include #include int main(int argc, char *argv)

sleep(10);

printf("\n%d - finished\n", getpid());

exit(exit_success);

}

結果:

結果很明顯了,0x並不是成對列印的。

Linux 程序間通訊之訊號量

訊號量是解決因多個程式同時訪問乙個共享資源而引發的一系列問題的,訊號量是0代表其他程式要暫時掛起,不能訪問訊號量控制的 區,訊號量為1,代表其他程式可以訪問訊號量控制的 區,這個訊號量也是在核心區的共享記憶體存放的,我們來看幾個關鍵函式 1 semget函式 它的作用是建立乙個新訊號量或取得乙個已有...

Linux程序間通訊之訊號量

linux程序間通訊之訊號量 訊號量是一種用於提供不同程序間或乙個給定程序的不同執行緒間同步手段的原語。在unix下有三種分別如下 在這裡只和大家分享下有關system v訊號量。system v通過定義計數訊號量集來對訊號量的操作,計數訊號量集是乙個或多個訊號量構成乙個集合,其中每個都是計數訊號量...

程序間通訊之訊號量

訊號量的本質是一種資料操作鎖,其本身不具有資料交換的能力,而是通過控制其他的通訊資源 檔案 外部裝置 來實現程序間通訊,它本身只是一種外部資源的標識。訊號量在此過程中負責資料的互斥 同步等功能。當請求乙個訊號量來表示資源時,程序需要讀取訊號量的值來判斷資源是否可用。大於0,資源可以請求,等於0,無資...