Linux作業系統——簡單程式同步
一、訊號量相關函式
1. 建立訊號量集
本次實驗使用訊號量機制來實現程式的同步與互斥,因此首先需要建立訊號量集。
使用函式semget可以建立訊號量集,它的原型如下:
int semget(key_t key, int nsems, int semflg)
其中,key是建立訊號量集的鍵,nsems是訊號量集中訊號量量的數量;
semflg是指定的選項及其許可權位,包含IPC_CREAT(建立新的訊號量集)、IPC_EXCEL(如果訊號量集已經存在,則返回錯誤)等。
這個函式建立的是一個訊號量集,其中包含多個訊號量,可以透過函式semop來訪問訊號量集中的某個訊號量,或者使用semctl函式來對訊號量進行操作,一般建立資料集後都要首先使用semctl對每個訊號量設定初始值。semop和semctl函式的介紹在下面。
2. 獲取訊號量集
一個程式建立號訊號量集後,另一個程式想要訪問這個訊號量集,可以使用semget函式傳入KEY值來獲取該訊號量集的id,該函式原型如下:
int semid = semget(KEY, 0, 0);
上述程式碼只為獲取一個已經存在的訊號量集,不需要nsems和semflg,全部為0即可。獲取成功會返回訊號量集id,如果獲取失敗的話會返回-1 。
3. 等待、通知訊號量集
使用semop函式可以訪問一個訊號量集,進行獲取(P操作)和釋放(V操作),其原型如下:
int semop(int semid,struct sembuf *sops,unsigned nsops)
semid是使用semget函式獲取到的訊號量集的id;
sops是一個sembuf型別的結構,用於描述訊號量的操作:等待、通知等,其定義如下:
struct sembuf{
short sem_num; // 要訪問的訊號量在訊號量集中的索引
short sem_op; // 對訊號量的操作,為負數是P操作,正數是V操作
short sem_flg; // 操作標誌,可以是0或IPC_NOWAIT(非阻塞方式)
}
nsops是指定訊號量集中操作的訊號量個數。
4. 控制訊號量集
要對整個訊號量集進行操作可以使用semctl函式,其原型如下:
int semctl(int semid, int semnum, int cmd, union semun arg)
semid是由semget函式返回的訊號量集id
semnum是訊號量在訊號量集中的索引
cmd是控制命令,用於對訊號量執行指定的操作,命令包括:
IPC_STAT:獲取訊號量集合的屬性資訊,將結果寫入指定的結構體中。
IPC_SET:設定訊號量集合的屬性資訊,使用指定的結構體中的值進行設定。
GETVAL:獲取指定訊號量的值。
SETVAL:設定指定訊號量的值。
GETALL: 獲取訊號量集合中所有訊號量的值
SETALL: 設定所有訊號量的值
GETPID:獲取最後一個執行 semop() 操作的程式 ID。
GETNCNT:獲取等待該訊號量值增加的程式數。
GETZCNT:獲取等待該訊號量值變為 0 的程式數。
IPC_RMID:刪除訊號量集合。
二、簡單程式同步
現在使用上面給出的函式編寫幾個程式實現程式同步。
訊號量機制實現程式同步需要使用一些簡單的訊號量集操作,包括建立訊號量集,P操作,V操作,刪除訊號量集。
1. 建立訊號量集
createSem.cpp
#include<iostream>
#include<sys/sem.h>
#include<sys/types.h>
#include<sys/ipc.h>
using namespace std;
#define KEY 2002
int main(){
int semid = semget(KEY, 1, IPC_CREAT);
semctl(semid, 0, SETVAL, 0);
}
上面程式碼使用semid函式建立一個只包含一個訊號量的訊號量集,隨後使用semctl將該訊號量的值初始化為0 。
2. P操作
p1.cpp
#include<iostream>
#include<sys/sem.h>
#include<sys/types.h>
#include<sys/ipc.h>
#define KEY 2002
using namespace std;
int main(){
int semid = semget(KEY, 0, 0);
struct sembuf *sops = new sembuf;
sops->sem_num = 0;
sops->sem_op = -1;
sops->sem_flg = 0;
if(semop(semid, sops, 1) == -1){
char err[] = "semop";
perror(err);
exit(1);
}
cout << "獲取成功" << endl;
return 0;
}
上一個程式createSem建立完訊號量集後,訊號量集就儲存在緩衝區中,此時另一個程式可以使用semget函式訪問該訊號量集,使用同樣的鍵值KEY就能訪問到上一個程式建立的訊號量集。
上述程式碼首先獲取已經建立好的訊號量集,隨後定義sembuf型別結構指標sops,設定訪問訊號量索引sem_num為0,訊號量操作sem_op為-1(p操作,訊號量減一),操作標誌為0 。接著就使用semop函式傳入sops對訊號量進行操作,如果操作失敗(如訊號量集不存在或訊號量索引非法等)就輸出錯誤資訊,結束程式。如果獲取成功則會執行下面的語句列印“獲取成功”,如果進行P操作時該訊號量為0,此時進行會阻塞,等待其他程式釋放訊號,為了簡化問題,一開始設定訊號量為0,此時執行p1程式一定會阻塞。
3. V操作
p2.cpp
#include<iostream>
#include<sys/sem.h>
#include<sys/types.h>
#include<sys/ipc.h>
#define KEY 2002
using namespace std;
int main(){
int semid = semget(KEY, 0, 0);
struct sembuf *sops = new sembuf;
sops->sem_num = 0;
sops->sem_op = 1;
sops->sem_flg = 0;
if(semop(semid, sops, 1) == -1){
char err[] = "semop";
perror(err);
exit(1);
}
return 0;
}
上面程式碼與p1基本時一樣的,只是修改了sem_op,改為1(V操作,訊號量加1),執行該程式後,對應訊號量會加一,原本阻塞的程式就能結束等待,繼續執行下去。
4. 刪除訊號量集
deletSem.cpp
訊號量集使用完畢後需要刪除訊號量集,使用semctl函式實現,控制命令選擇IPC_RMID。
#include<iostream>
#include<sys/sem.h>
#include<sys/types.h>
#include<sys/ipc.h>
using namespace std;
#define KEY 2002
int main(){
int semid = semget(KEY, 0, 0);
semctl(semid, 0, IPC_RMID, 0);
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70001647/viewspace-2998725/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [作業系統]程序同步作業系統
- 作業系統中程式簡介作業系統
- 【Linux】Linux作業系統 程式管理Linux作業系統
- 簡單介紹Linux作業系統的九大特點!Linux作業系統
- 作業系統筆記(八)程式同步附加篇作業系統筆記
- 作業系統 Linux下的程式作業系統Linux
- 作業系統: Unix作業系統演進簡史作業系統
- linux作業系統修改共享記憶體的簡單方法(轉)Linux作業系統記憶體
- 作業系統簡介作業系統
- 作業系統的程式/執行緒同步問題作業系統執行緒
- Linux 作業系統Linux作業系統
- Linux作業系統Linux作業系統
- 【linux】Linux作業系統Linux作業系統
- 1.3作業系統簡介作業系統
- 作業系統核心簡介作業系統
- 作業系統作業單元考核(附答案)作業系統
- Linux作業系統之Shell程式設計Linux作業系統程式設計
- Linux作業系統概述Linux作業系統
- 作業系統與Linux作業系統Linux
- 作業系統-程式管理作業系統
- 【作業系統之程式】作業系統
- 【Linux】Linux作業系統 設定GRUB選單密碼Linux作業系統密碼
- 作業系統是什麼?Linux是什麼作業系統?作業系統Linux
- Linux 作業系統如何啟用 secure boot(不限發行版)(簡單的方法)Linux作業系統boot
- Linux作業系統 程式之間的通訊Linux作業系統
- 理解linux/unix作業系統守護程式(轉)Linux作業系統
- 作業系統備份清單作業系統
- 作業系統知識回顧(3)--程式的同步與通訊作業系統
- Linux 作業系統!開篇!!!Linux作業系統
- 科普帖:Linux作業系統Linux作業系統
- Linux作業系統基礎Linux作業系統
- Linux作業系統 paste命令Linux作業系統AST
- LINUX作業系統runuser用法Linux作業系統
- 桌面 Linux 作業系統不死Linux作業系統
- linux作業系統介紹Linux作業系統
- 【Linux】Linux作業系統 配置sudoLinux作業系統
- 作業系統篇-程式管理作業系統
- 【作業系統】程式管理(二)作業系統