【ARM&Linux】Linux訊號量互斥程式設計
阿新 • • 發佈:2019-02-19
《訊號量互斥程式設計示例演示》
/****************************************************************************************
* 檔名: a_pro.c
* 建立者:
* 時 間:
* 聯 系:
* 簡 介: 程序A程式,函式參考文件《unix環境高階程式設計》
*****************************************************************************************/
/****************************** *****************************
函式學習:
1、建立/開啟 semget(引數一,引數二,引數三)
引數一:鍵值
引數二:要建立的訊號量集合的數目
引數三:如果鍵值不存在且引數三是IPC_CREAT,則會建立訊號量
返回:訊號量集合的識別符號
2、操作 int semop(int semid, struct sembuf *sops, unsigned nsops);
引數一:訊號量集合的標誌符
引數二:
引數三:
【例項演示】:
兩個程序都要向檔案tmp中寫入,程序A寫入第一次後,
假設有中斷請求去處理別的事情了(這裡用sleep表示),
那麼程序B就會在程序A還未寫完的情況下,寫入程序B的內容,
就會造成寫入混亂.
由此引入互斥訊號量。
過程:
a建立並獲取訊號量-> 執行 -> a釋放訊號量
訊號量使用過程:
1、建立訊號量集合識別符號
2、建立訊號量集合
3、檢查訊號量初始值是否等於建立的訊號量個數
4、獲取訊號量
5、需要加互斥的程式程式碼
6、釋放訊號量
b程序執行過程:
b程序獲取訊號量->獲取成功->b程序執行
->獲取失敗->等待a程序釋放訊號量
a程序執行過程:
a程序獲取訊號量->獲取成功->執行程式碼->睡眠->執行程式碼->釋放訊號量
************************************************************/
#include <unistd.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <string.h>
#define DEBUG_INFO(x) printf(x)
const char* const pStr = "process b write \n";
int main()
{
key_t key;
int semid;
int fd;
struct sembuf sops;
//---獲取訊號量集合識別符號 ---//
key = ftok("/home", 1);
//--- 獲得訊號量集合ID ---//
semid = semget(key, 0, IPC_CREAT);
if((fd=open("./tmp.txt", O_APPEND|O_RDWR)) < 0)
{
DEBUG_INFO("程序B檔案開啟失敗!\n");
}
//--- 獲取訊號量 ---//
sops.sem_num = 0; //此值表示要操作第幾個訊號量
sops.sem_op = -1; //此值如果為正值,則表示釋放訊號量;如果為負值,則表示獲取訊號量
semop(semid, &sops, 1);
if((write(fd, pStr, strlen(pStr))) < 0)
{
DEBUG_INFO("process b write failed \n");
}
//--- 釋放訊號量 ---//
sops.sem_num = 0;
sops.sem_op = 1;
semop(semid, &sops, 1);
close(fd);
return 0;
}
/****************************************************************************************
* 檔名: b_pro.c
* 建立者:
* 時 間:
* 聯 系:
* 簡 介: 程序B程式,函式參考文件《unix環境高階程式設計》
*****************************************************************************************/
#include <unistd.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <string.h>
#define DEBUG_INFO(x) printf(x)
const char* const pStr = "process a write 1 \n";
const char* const pStr2 = "process a write 2 \n";
int main()
{
key_t key;
struct sembuf sops;
int semid;
int fd;
//--- 建立訊號量集合識別符號 ---//
key = ftok("/home", 1);
//--- 建立一個訊號量 ---//
semid = semget(key, 1, IPC_CREAT);
//--- 檢查訊號量初始值是否為1 ---//
if((semctl(semid, 0, GETVAL)) != 1)
{
semctl(semid, 0, SETVAL, 1);
}
if((fd=open("./tmp.txt", O_APPEND|O_RDWR)) < 0)
{
DEBUG_INFO("process a open err \n");
}
//--- 獲取訊號量 ---//
sops.sem_num = 0;
sops.sem_op = -1;
semop(semid, &sops, 1);
if((write(fd, pStr, strlen(pStr))) < 0)
{
DEBUG_INFO("process a write err \n");
}
sleep(5);
if((write(fd, pStr2, strlen(pStr2))) < 0)
{
DEBUG_INFO("process a write 2 err \n");
}
//--- 釋放訊號量 ---//
sops.sem_num = 0;
sops.sem_op = 1;
semop(semid, &sops, 1);
close(fd);
return 0;
}
【Makefile】
開啟兩個終端,在第一個終端上執行./a.exe,迅速切換到第二個終端執行./b.exe,cat tmp.txt檔案內容
【結果如圖】: