程序間通訊之訊號量

2021-08-28 09:45:44 字數 3886 閱讀 8332

一、訊號量的定義和原理

1、一些概念

舉個例子,就是兩個程序共享訊號量sv,一旦其中乙個程序執行了p(sv)操作,它將得到訊號量,並可以進入臨界區,使sv減1。而第二個程序將被阻止進入臨界區,因為當它試圖執行p(sv)時,sv為0,它會被掛起以等待第乙個程序離開臨界區域並執行v(sv)釋放訊號量,這時第二個程序就可以恢復執行。

2、訊號量的定義

為了防止出現因多個程式同時訪問乙個共享資源而引發的一系列問題,我們需要一種方法,它可以通過生成並使用令牌來授權,在任一時刻只能有乙個執行執行緒訪問**的臨界區域。臨界區域是指執行資料更新的**需要獨佔式地執行。而訊號量就可以提供這樣的一種訪問機制,讓乙個臨界區同一時間只有乙個執行緒在訪問它,也就是說訊號量是用來調協程序對共享資源的訪問的

3、訊號量的原理

1. 測試控制該資源的訊號量;

2.若訊號量的值為正,則程序可以使用該資源,程序的訊號量值減1,表示乙個資源被使用;

3.若此訊號量為0,則程序進入休眠,直到該訊號量值大於0

4.當程序不再使用乙個由乙個訊號控制的共享資源時,該訊號量加1,如果有程序正在休眠等待該訊號量,則該程序會被喚醒

二、訊號量的使用

1、一些資料結構的定義

(1)semid_ds

核心為每個訊號量集合維護著乙個結構體:

struct semid_ds
(2)semun(必須定義該聯合體)

union semun
(3)sembuf(訊號量運算元組)

struct sembuf
2、semget函式

#include

intsemget

(key_t key,

int num_sems,

int sem_flags)

;

返回值:成功返回乙個相應訊號識別符號(非零),失敗返回-1。

3、semop函式

#include

intsemop

(int sem_id,

struct sembuf *sem_opa, size_t num_sem_ops)

;

返回值:成功返回0,失敗返回-1。

4、semctl函式

#include

intsemctl

(int sem_id,

int sem_num,

int command,..

.);

返回值:成功返回0,失敗返回-1。

三、訊號量的demo

// comm.h

#ifndef _mysem_h_

#define _mysem_h_

#include

#include

#include

// ftok

#include

#include

#include

#define pathname "."

// ftok 中生成key值 . 表示當前路徑

#define proj_id 56

// ftok 中配合pathname 生成唯一key值

union semun

;int

create_sems

(int nums)

;// 建立含有nums個訊號量的集合

intget_sems()

;// 獲取訊號量

// 初始化semid對應的訊號量集中編號為which的訊號量值為value

intinit_sems

(int semid ,

int which,

int value)

;int

destroy_sems

(int semid)

;// 釋放該訊號量集

intp

(int semid,

int which)

;// 表示分配 訊號量值-1

intv

(int semid,

int which)

;// 表示釋放 訊號量值+1

#endif

/* _mysem_h_ */

// comm.cpp

#include

"comm.h"

// 建立訊號量和獲取訊號量公用函式

static

intcomm_sem

(int nums ,

int semflag)

// 用來建立乙個訊號集,或者獲取已存在的訊號集。

int semid =

semget

(key, nums, semflag);if

( semid <0)

return semid;

}// 初始化運算元組

static

intcomm_sem_op

(int semid,

int which,

int op)

// 建立含有nums個訊號量的集合

intcreate_sems

(int nums)

// 初始化訊號集

intinit_sems

(int semid ,

int which,

int value)

return0;

}// 獲取訊號量

intget_sems()

// 釋放該訊號量集

intdestroy_sems

(int semid)

return0;

}// p操作

intp

(int semid,

int which)

// v操作

intv

(int semid,

int which)

// test.cpp

#include

"comm.h"

#include

#include

intmain()

elseif(

0== id)

// 子程序

}else

// 父程序

wait

(null);

}destroy_sems

(semid)

;return0;

}

四、訊號量的總結

訊號量是乙個特殊的變數,程式對其訪問都是原子操作,且只允許對它進行等待(即p(訊號變數))和傳送(即v(訊號變數))資訊操作。我們經常通過訊號來解決多個程序對同一資源的訪問競爭的問題,使在任一時刻只能有乙個執行執行緒訪問**的臨界區域,也可以說它是協調程序間的對同一資源的訪問權,也就是用於同步程序的

【優點】:

【缺點】:

參考:

程序間通訊之訊號量

訊號量的本質是一種資料操作鎖,其本身不具有資料交換的能力,而是通過控制其他的通訊資源 檔案 外部裝置 來實現程序間通訊,它本身只是一種外部資源的標識。訊號量在此過程中負責資料的互斥 同步等功能。當請求乙個訊號量來表示資源時,程序需要讀取訊號量的值來判斷資源是否可用。大於0,資源可以請求,等於0,無資...

程序間通訊之訊號量

訊號量的本質是一種資料操控鎖,它本身不具有資料交換的功能,而是通過來控制其他的通訊資源來實現程序間通訊的,訊號主要負責資料的同步與互斥功能。程序請求乙個使用訊號量來表示的資源時,首先要讀取訊號量的值來判斷資源是否能被使用,若訊號量的值大於0,資源可用,等於0,無資源可用,同時程序會進入睡眠狀態,直到...

程序間通訊之 訊號量

訊號量相當於記錄資源能同時被多少個程序訪問。訊號量的作用 程序間同步控制。訊號量有乙個初值,每當有程序申請使用訊號量,就會通過乙個p操作對訊號量進行 1操作,當計數器減到0的時候就說明沒有資源了,其他程序要想訪問就必須等待,當該程序執行完這段工作之後,就會執行v操作,即對訊號量進行 1操作。標頭檔案...