1. 程式人生 > >【ARM&Linux】Linux訊號量互斥程式設計

【ARM&Linux】Linux訊號量互斥程式設計

《訊號量互斥程式設計示例演示》

/****************************************************************************************
* 檔名: 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檔案內容

【結果如圖】:

這裡寫圖片描述