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

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

一、訊號量(semaphore)

        在程序互斥中,訊號量主要用來保護臨界資源。程序通過訊號量來判斷

是否能夠訪問該共享資源。(當然,後面我們還會用來控制程序同步)。

二、訊號量型別

1、二值訊號量:訊號量的取值為 0 或者 1

2、計數訊號量:訊號量的取值為任意非負數

三、鍵值 : 檔案標示符 + 專案ID

1、任意指定一個數:若該數已被使用,則不能與訊號量關聯(失敗)

2、構造一個數:使用ftok()構造

四、函式學習

1、建立 / 開啟訊號量集合:semget

1)函式原型

int semget(key_t key, int nsems, int semflg);

2)所屬標頭檔案

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

3)返回值

成功: 返回訊號量集合識別符號(非負整數); 當訊號量<0時訪問該訊號量的其他程序等待

失敗: -1

4)引數說明

key: 訊號量的鍵值

nsems: 訊號量的數目

semflg: 同open()函式的許可權位

2、操作訊號量:semop

1)函式原型

int semop(int semid, struct sembuf *sops, unsigned nsops);

2)所屬標頭檔案

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

3)返回值

成功: 0

失敗: -1

4)引數說明

semid: 要操作的訊號量集合的識別符號

sops: 對訊號量執行什麼操作

nsops: 要操作的訊號量數目

struct sembuf sops{

unsigned short sem_num;  /* 訊號量序號 */

short          sem_op;   /* 對訊號量操作 */

short          sem_flg;  /* operation flags */

}

3、鍵值轉換:ftok

1)函式原型

key_t ftok(const char *pathname, int proj_id);

2)所屬標頭檔案

#include <sys/types.h>

#include <sys/ipc.h>

3)返回值

成功: 返回生成的鍵值

失敗: -1

4)引數說明

pathname: 包含路徑的檔名

proj_id: 專案序號

4、訊號量控制操作:semctl

1)函式原型 

int semctl(int semid, int semnum, int cmd, ...);

2)所屬標頭檔案

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

3)返回值 

成功: 返回一個非負整數(取決於cmd)

失敗: -1

4)引數說明

semid: 訊號量集合

semnum: 集合中的訊號量序號

cmd: 命令

* 最佳實踐  - 1:

/* op_1.c */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>

#define FILE_NAME "./BOARD.TXT"

void main()
{
	int fd = 0;
	key_t key = 0;
	int semid = 0;
	int sem_val = 0;
	struct sembuf sops;

	/* 建立鍵值. */
	key = ftok("/home/taylor/linux-3/signal-process/BOARD.TXT",1);

	/* 建立並開啟訊號量集合. */
	semid = semget(key, 1, IPC_CREAT);
	
	/* 設定訊號量初值為1.預設不為0 */
	sem_val = semctl(semid, 0, SETVAL, 1);

	printf("Semaphore init value is : %d\n", sem_val);

	/* 開啟資訊檔案. */
	fd = open(FILE_NAME, O_RDWR | O_APPEND);

	/* 獲取訊號量.*/
	sops.sem_num = 0;
	sops.sem_op = -1;
	semop(semid, &sops, 1);

	/* 插入資料. */
	write(fd, "I Love ", 7);

	sleep(10);  //等待, 這裡執行op_2, 檢測是否互斥

	write(fd, "You.", 4);

	/* 釋放訊號量. */
	sops.sem_num = 0;
	sops.sem_op = 1;
	semop(semid, &sops, 1);

	/* 關閉檔案. */
	close(fd);
}

* 最佳實踐 - 2:

/* op_2.c */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>

#define FILE_NAME "./BOARD.TXT"

void main()
{
	int fd = 0;
	key_t key = 0;
	int semid = 0;
	int sem_num = 0;
	struct sembuf sops;

	/* 建立鍵值. */
	key = ftok("/home/taylor/linux-3/signal-process/BOARD.TXT",1);
	
	/* 開啟訊號量集合. */
	semid = semget(key, 1, IPC_CREAT);

	/* 獲取訊號量初始化. */
	sem_num = semctl(semid, 0, GETVAL);

	printf("Student2 get init value is: %d\n", sem_num);

	/* 開啟資訊檔案. */
	fd = open(FILE_NAME, O_RDWR | O_APPEND);

	/* Get semaphore. */
	sops.sem_num = 0;
	sops.sem_op = -1;  //當訊號量<0時, 執行等待
	semop(semid, &sops, 1);

	/* 插入資訊,看看是否插隊op_1 */
	write(fd, "pig is you ", 11);

	/* Release semaphore. */
	sops.sem_num = 0;
	sops.sem_op = 1;
	semop(semid, &sops, 1);

	close(fd);
}

輸出:

* 先後臺執行op_1 # ./op_1 &

* 再執行op_2 # ./op_2

* 從結果可以看出, 若在sleep(10)等待時沒有互斥現象, 則輸出內容為: I Love pig is you You. 資訊將錯亂

相關推薦

Linux多執行緒同步與互斥的區別

同步與互斥這兩個概念經常被混淆,所以在這裡說一下它們的區別。 一、同步與互斥的區別 1. 同步 同步,又稱直接制約關係,是指多個執行緒(或程序)為了合作完成任務,必須嚴格按照規定的 某種先後次序來執行。 例如,執行緒 T2 中的語句 y 要使用執行緒

Linux訊號通訊程式設計訊號互斥程式設計

一、訊號量(semaphore)         在程序互斥中,訊號量主要用來保護臨界資源。程序通過訊號量來判斷 是否能夠訪問該共享資源。(當然,後面我們還會用來控制程序同步)。 二、訊號量

ARM&LinuxLinux訊號互斥程式設計

《訊號量互斥程式設計示例演示》 /**************************************************************************************** * 檔名: a_pro.c * 建立者:

5、Linux系統編程環境變

第一次 的區別 nvi 用戶目錄 mail 操作 key 推薦 一行 前言   1. 環境變量是操作系統環境設置的變量,適用於整個系統的用戶進程;   2. 環境變量可以在命令中設置,但是用戶註銷的時候將會丟失這些設置值;   3. 若要重復適用,則最好在.profile中

Linux學習筆記八Linux程式設計-編譯(gcc)與除錯(gdb)

【注】文章中的所有截圖均為centos下實驗結果,親測命令正確= ̄ω ̄= 【參考資料】《Linux從入門到精通(第2版)》劉憶智 等編著 1、編譯一個C程式:以用vim寫成的summa

Linux探索之旅第一部分第三課:測試並安裝Ubuntu

u盤 nco 過程 sans ubunt windows u盤啟動盤 系統 .com 內容簡單介紹 1、第一部分第三課:測試並安裝Ubuntu 2、第一部分第四課預告:磁盤分區 測試並安裝Ubuntu 大家好,經過前兩個比較偏理論(是否

Linux數據庫Redis安裝配置

con debug top size 日誌 stream oca mono onf 一,Redis配置 1、下載安裝 $ wget http://download.redis.io/releases/redis-2.8.17.tar.gz $ tar xzf re

Linux探索之旅第四部分第三課:文件傳輸,瀟灑同步

命令行 上傳文件 文件夾 images lsh wget命令 ace 目標 wechat 內容簡單介紹 1、第四部分第三課:文件傳輸。瀟灑同步 2、第四部分第四課:分析網絡。隔離防火 文件傳輸。瀟灑同步 這一課的內容相

3、Linux系統編程系統目錄詳解

升級 user ssa pci edi 靜態 描述 com 沒有 Linux系統目錄詳解 一、Linux系統目錄結構 1、根目錄/   這就是根目錄。對你的電腦來說,有且只有一個根目錄。所有的東西,我是說所有的東西都是從這裏開始。舉個例子:當你在終端裏輸入“/home”,

Linux動態庫目錄增加linux動態庫目錄

動態庫目錄 在Linux下面動態庫目錄載入入口在**/etc/ld.so.conf**檔案 預設該檔案只有一行“include /etc/ld.so.conf.d/*.conf”,其中ld.so.conf.d是預設動態庫的配置的存放目錄。 我們用 sudo vim /etc/ld.s

JVM第八篇:Java併發程式設計:用AQS寫一把可重入鎖

前一篇部落格Java併發程式設計:自己動手寫一把可重入鎖詳述瞭如何用synchronized同步的方式來實現一把可重入鎖,今天我們來效仿ReentrantLock類用AQS來改寫一下這把鎖。要想使用AQS為我們服務,首先得弄懂三個問題:AQS是什麼?AQS已經做了什麼以及我們還需要做些什麼?

JVM第七篇:Java併發程式設計:自己動手寫一把可重入鎖

關於執行緒安全的例子,簡而言之就是多個執行緒在同時訪問或修改公共資源的時候,由於不同執行緒搶佔公共資源而導致的結果不確定性,就是在併發程式設計中經常要考慮的執行緒安全問題。前面的做法是使用同步語句synchronized來隱式加鎖,現在我們嘗試來用Lock顯式加鎖來解決執行緒安全的問題,先來

成都網優谷在學校學程式設計好,還是去培訓好?

現在很多培訓機構宣傳,什麼JAVA三個月培訓月薪多少多少的,崁入式程式設計培訓半年月薪又是多少多少的。這些資料讓人看著確實是動心啊。可是對於現在網際網路時代,IT行業高新確實是事實,但也不一定想這些培訓機構說的那樣,只需要培訓幾個月就能 夠輕輕鬆鬆月薪過萬。這只是培訓機構為了吸引學員而做出的宣傳而已。

Linux學習筆記11移動檔案,目錄的mv命令以及關於檢視檔案的技巧

首先給大家分享一下移動檔案、目錄的命令—mv命令(move) (這裡不會像前面那麼詳細地說,因為與前一篇的cp命令有很多相同點,重頭戲在檢視檔案的技巧) mv命令:用於移動檔案或者目錄 mv /tmp/CJlinux/1/2/1.txt /t

圖知識小結6-DFS應用CCF201709-4通訊網路

#include <bits/stdc++.h> using namespace std; const int MAX_EDGE = 10005; const int MAX_VERTICES = 1005; int conn[MAX_VERTICES][MAX_VERTICES]; /

Linux之旅-1VMware虛擬機器中的Centos和windows共享資料夾

一、開啟虛擬機器,進入安裝好的centos系統,點選VM頂部導航欄中的“虛擬機器”按鈕,進入子選單選擇“安裝VMware Tools”,如下圖(我的已安裝過,因此顯示的是重新安裝) 二、在cent

Linux之旅-3vi和vim編輯器

一、vi和vim介紹 所有的Linux系統都會內建vi文字編輯器。vim具有程式編輯能力,可看作是vi的增強版,可以主動的以字型顏色辨別程式碼語法的正確性,方便程式設計,程式碼補充、編譯及錯誤跳轉等方便程式設計的功能豐富。 二、vi和vim的三種常見模式 2.1正常模式

Linux之旅-4Linux關機重啟和遠端登入登出

一、關機與重啟相關命令的使用 關機與重啟相關命令 命令 功能 shutdown -h now 立即關機 shutdown -h 1 1分鐘後關機 shutdown -r

Linux之旅-7Linux使用者和組的配置檔案

一、使用者(user)的配置檔案 1.1配置檔案位置 /etc/passwd 1.2作用 記錄使用者的各種資訊。 1.3檔案每行的含義 使用者名稱:口令:使用者標識號:組標識號:註釋性描述:

Linux之旅-8Linux執行級別和找回root密碼

一、Linux執行級別 在Linux系統中,我們可以開啟/etc/inittab檔案檢視,Linux共有七個執行級別(有一個級別4為保留級別)下面是檔案內容; # inittab is only u