Ubuntu下Linux程序間通訊 訊號量

2021-10-07 02:00:10 字數 3423 閱讀 9894

linux提供了多種程序間通訊的方法,常見有管道(匿名)、fifo(有名管道)、訊息佇列、訊號量、共享記憶體,socket通訊。

linux程序間通訊——匿名管道

linux程序間通訊——fifo(有名管道)

linux程序間通訊——訊息佇列

linux程序間通訊——訊號量

linux程序間通訊——共享記憶體

4.訊號量

訊號量(semaphore)是一種用於提供不同程序之間或者乙個給定的不同執行緒間同步手段的原語。訊號量多用於程序間的同步與互斥,主要有三點:

①同步:處理競爭就是同步,安排程序執行的先後順序就是同步,每個程序都有一定的先後執行順序。

②互斥:互斥訪問不可共享的臨界資源,同時會引發兩個新的控制問題(互斥可以說是特殊的同步)。

③競爭:當併發程序競爭使用同乙個資源的時候,我們就稱為競爭程序。

共享資源通常分為兩類:一類是互斥共享資源,即任一時刻只允許乙個程序訪問該資源;另一類是同步共享資源,即同一時刻允許多個程序訪問該資源;訊號量是解決互斥共享資源的同步問題而引入的機制。

訊號量工作機制:

可以直接理解成計數器,訊號量會有初值(一般》0),每當有程序申請使用訊號量,通過乙個p操作來對訊號量進行-1操作,當計數器減到0的時候就說明沒有資源了,其他程序要想訪問就必須等待,當該程序執行完這段工作(稱之為臨界區)之後,就會執行v操作來對訊號量進行+1操作。

臨界區:臨界區指的是乙個訪問共用資源(例如:共用裝置或是共用儲存器)的程式片段,而這些共用資源又無法同時被多個執行緒訪問的特性。

臨界資源:只能被乙個程序同時使用(不可以多個程序共享),要用到互斥。

訊號量跟互斥鎖很相似。

當有程序要求使用共享資源時,需要執行以下操作:

①系統首先要檢測該資源的訊號量;

②若該資源的訊號量值大於0,則程序可以使用該資源,此時,程序將該資源的訊號量值減1;

③若該資源的訊號量值為0,則程序進入休眠狀態,直到訊號量值大於0時程序被喚醒,訪問該資源;

當程序不再使用由乙個訊號量控制的共享資源時,該訊號量值增加1,如果此時有程序處於休眠狀態等待此訊號量,則該程序會被喚醒。

訊號量集和訊號量

//訊號量集

/* data structure describing a set of semaphores. */

struct semid_ds

;//訊號量

/* data structure describing each of semaphores. */

struct sem

;

關鍵**

#include

#include

//建立訊號量

intsemget

(key_t key,

int nsems,

int sem***)

;//訊號量控制(第四個引數為可選引數)

intsemctl

(int semid,

int semnum,

int cmd,..

.);//可選引數————設定訊號量初值結構體

union semun

;//訪問訊號量

intsemop

(int semid,

struct sembuf *sops,

unsigned nsops)

;struct sembuf

semget函式中的key是訊號量標籤,nesms是訊號量的數量,sem***是設定模式。成功返回semid訊號量id,失敗返回-1。

semctl函式中的semid是訊號量id,semnum是指定要操作第幾個訊號量(從0開始),cmd是具體的操作一般有:

①setval :設定單個訊號量的初值

②setall: 設定所有的訊號量的初值(semnum將會被忽略)

③ipc_rmid :刪除訊號集

…:第四個引數,是乙個不定引數,比如要獲取訊號量的資訊,那麼第四個引數就是結構體;比如要設定訊號量的值,那麼第四個引數就是值的聯合體

成功返回0,失敗返回-1。

semget函式中的semid是訊號量id,sops用於設定:

①sem_num:訊號量編號

②sem_op:訊號量一次pv操作時加減的數值,-1 即p操作,獲取資源,+1 即v操作,釋放資源

③sem_flag:ipc_nowait:退出,沒有釋放資源;ipc_undo :退出,會釋放資源。

nsops是操作結構的數量,恆大於或等於1。

例項

semtest.c

#include

#include

#include

#include

#include

//設定初值結構體

union semun

;//獲取資源

intsem_p

(int semid)

return0;

}//釋放資源

intsem_v

(int semid)

return0;

}int

main()

union semun sem_val;

//設定訊號量初值

sem_val.val=1;

ret=

semctl

(semid,

0,setval,sem_val);if

(ret==-1

)//建立程序

int pid=-1

; pid=

fork()

;if(pid==-1

)else

if(pid==0)

printf

("son folk sem get success!\n");

sleep(1

);//釋放訊號量資源

ret=

sem_v

(semid);if

(ret==-1

)}}else

printf

("father folk sem get success!\n");

sleep(1

);//釋放訊號量資源

ret=

sem_v

(semid);if

(ret==-1

)}}//刪除訊號集

ret=

semctl

(semid,

0,ipc_rmid,sem_val);if

(ret==-1

)return0;

}

每日乙個知識點,執行緒鎖有互斥鎖、條件鎖、自旋鎖、讀寫鎖、遞迴鎖,一般來說鎖的功能越強大,效能越差。

Ubuntu下Linux程序間通訊 匿名管道

linux程序間通訊 匿名管道 linux程序間通訊 fifo 有名管道 linux程序間通訊 訊息佇列 linux程序間通訊 訊號量 linux程序間通訊 共享記憶體 linux提供了多種程序間通訊的方法,常見有管道 匿名 fifo 有名管道 訊息佇列 訊號量 共享記憶體,socket通訊。1.匿...

Ubuntu下Linux程序間通訊 共享記憶體

linux提供了多種程序間通訊的方法,常見有管道 匿名 fifo 有名管道 訊息佇列 訊號量 共享記憶體,socket通訊。linux程序間通訊 匿名管道 linux程序間通訊 fifo 有名管道 linux程序間通訊 訊息佇列 linux程序間通訊 訊號量 linux程序間通訊 共享記憶體 5.共...

linux下程序間通訊

linux下程序間通訊的幾種主要手段簡介 管道 pipe 及有名管道 named pipe 管道可用於具有親緣關係程序間的通訊,有名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關係程序間的通訊 訊號 signal 訊號是比較複雜的通訊方式,用於通知接受程序有某種事件發...