Linux初學第十二天 程序間通訊五 訊號量

2021-10-10 18:07:32 字數 3857 閱讀 5793

訊號量(semaphore)與已經學過的的ipc結構不同,它是乙個計數器,訊號量用於實現程序間的互斥與同步,而不是用於儲存程序間的通訊資料。舉例子來理解這句話:

把乙個臨界資源(也可以認為是共享記憶體)比作乙個上了鎖的房間,某人比作乙個程序,而開鎖的鑰匙就是訊號量。某人有鑰匙的話,就能開鎖進入房間裡,做它需要做的事情,如果這時候有第二個人想進入房間裡的話,是進不去的,因為它沒有鑰匙(訊號量)。直到進去的那個人除了房間把鑰匙放在某個地方,然後第二人拿到了鑰匙,才能渠道房間裡去。這鑰匙起到的作用就是訊號量。

全都放在了標頭檔案中

建立或獲取乙個訊號量組

引數說明:

1.key索引值,可使用ftok函式來獲取;

2.num_sems訊號量的個數;

3.sem_flags傳遞ipc_creat加上許可權可以建立訊號量集;

返回值:成功返回訊號集的id;失敗返回 -1 ;

用法:

key_t key;

key=

ftok

(".",1

);int semid=

semget

(key,

1,ipc_creat|

0666);

//建立乙個訊號量

操作訊號量組函式。有兩種操作,p操作:即上面例子提到的拿鑰匙,v操作:上面例子提到的放鑰匙。

引數說明:

1.semid被操作目標訊號量的id號;

2.semoparray結構體陣列,它有三個成員:

(1)sem_num:需要操作第幾個訊號量;

(2)sem_op:訊號量的值,-1為減1

(3)sem_***:一般賦值sem_undo;

3.semops:semoparray 陣列的個數。

返回值:成功返回0;失敗返回 -1 ;

p操作用法:

struct sembuf *semoparry;

semoparry=

(struct sembuf *

)malloc

(sizeof

(struct sembuf));

semoparry->sem_num=0;

semoparry->sem_op=-1

;semoparry->sem_***=sem_undo;

semop

(semid,semoparry,1)

;

v操作用法:

struct sembuf *semoparry;

semoparry=

(struct sembuf *

)malloc

(sizeof

(struct sembuf));

semoparry->sem_num=0;

semoparry->sem_op=1;

semoparry->sem_***=sem_undo;

semop

(semid,semoparry,1)

;

控制訊號量函式。用來控制訊號,比如初始化,移除訊號量等。

引數說明:

1.semid被操作目標訊號量的id號;

2.sem_num訊號量的個數,即需要操作第幾個訊號量;

3.cmd操作指令,它有幾個巨集,我們這裡用setval(操作訊號量的值)

4.其他這個引數,是配合setval指令來使用,它是個聯合體而且需要定義這個聯合體:

union semun 

;

返回值:成功返回0;失敗返回 -1 ;

用法:

union semun 

;union semun value;

value.val=1;

semctl

(semid,

0,setval,value)

;

認識了這三個api之後,我們可以做個小實驗,來看看訊號量是怎麼實現管控程序。

**:

#include

#include

#include

#include

#include

//int semget(key_t key, int nsems, int sem***);

//定義聯合體

union semun

;//pgetkey p操作

void

pgetkey

(int semid)

else

}//vgetkey v操作

void

vgetkey

(int semid)

else

}int

main

(int argc,

char

**ar**)

else

if(pid==0)

else

return0;

}

因為semctl時,把訊號量的值設定為 0;所以父程序p操作(拿鑰匙)時會阻塞,當子程序v操作後,重新放出了鑰匙。父程序才能執行列印。所以這個執行結果就是子程序先執行,然後父程序才執行。

執行結果:

程序間通訊(ipc)學到現在,就可結束了了。回顧一下程序間通訊都學了寫啥:

一、通道和命名通道fifo:是個半雙工的通訊方式,讀寫不可以同時進行,必須讀完後關閉通道,然後才可以寫入。而fifo相當於乙個檔案,可以用普通的檔案操作來操作fifo。

二、訊息佇列:訊息佇列是個鍊錶,發訊息就是往訊息煉表裡新增乙個節點(訊息的結構體),而且兩個不相關的程序都可以操作訊息佇列。

三、共享記憶體:區別於兩個程序之間的另外一塊記憶體空間,而且可以連線到程序的空間當中,可以使用普通的指標操作來訪問共享記憶體。

四、訊號:linux作業系統中已經定義了64個訊號,我們可以通過這些訊號來控制程序(入門版)或傳遞訊息(高階版);

五:訊號量:區別於前四個ipc結構,不是一種程序通訊方式,我們可以理解為它起到乙個程序排程的作用。

JS第十二天

a dom2級規範定義了一些模組,用於dom1級,dom2級核心 為了不同的dom型別引入了一些與xml命名空間有關的方法,這些變化只在使用xml或者是xhtml文件的時才有用 對於httml文件沒有實際的意義,除了與xml命名空間有關的方法外,dom級核心 還定義了以程式設計凡事建立documen...

java第十二天

b 案例演示 a 非正規表示式實現 b 正規表示式實現 b 案例演示 b 案例演示 1 a b c 2 a 3 b c 4 c 組零始終代表整個表示式。b 案例演示 a 切割 需求 請按照疊詞切割 sdqqfgkkkhjppppkl b 替換 需求 我我 我 我.要 要要 要學 學學.學.編.編編....

springboot第十二天

springboot1.0,2014年發布,預設資料庫連線池為 tomcat jdbc pool springboot2.0,2018年3月1日發布,預設資料庫連線池為 hikari 1.專案建立選擇元件 mysql,jdbc web spring datasource username root ...