信號量列程
『壹』 什麼叫信號量它由哪幾部分組成信號量的值有什麼含義
信號量(Semaphore),有時被稱為信號燈,是在多線程環境下使用的一種設施,是可以用來保證兩個或多個關鍵代碼段不被並發調用。在進入一個關鍵代碼段之前,線程必須獲取一個信號量;一旦該關鍵代碼段完成了,那麼該線程必須釋放信號量。其它想進入該關鍵代碼段的線程必須等待直到第一個線程釋放信號量。為了完成這個過程,需要創建一個信號量VI,然後將Acquire Semaphore VI以及Release Semaphore VI分別放置在每個關鍵代碼段的首末端。確認這些信號量VI引用的是初始創建的信號量。
描述
編輯
以一個停車場的運作為例。簡單起見,假設停車場只有三個車位,一開始三個車位都是空的。這時如果同時來了五輛車,看門人允許其中三輛直接進入,然後放下車攔,剩下的車則必須在入口等待,此後來的車也都不得不在入口處等待。這時,有一輛車離開停車場,看門人得知後,打開車攔,放入外面的一輛進去,如果又離開兩輛,則又可以放入兩輛,如此往復。
在這個停車場系統中,車位是公共資源,每輛車好比一個線程,看門人起的就是信號量的作用。
分類
編輯
整型信號量(integer semaphore):信號量是整數
記錄型信號量(record semaphore):每個信號量s除一個整數值s.value(計數)外,還有一個進程等待隊列s.L,其中是阻塞在該信號量的各個進程的標識
二進制信號量(binary semaphore):只允許信號量取0或1值
每個信號量至少須記錄兩個信息:信號量的值和等待該信號量的進程隊列。它的類型定義如下:(用類PASCAL語言表述)
semaphore = record
value: integer;
queue: ^PCB;
end;
其中PCB是進程式控制制塊,是操作系統為每個進程建立的數據結構。
s.value>=0時,s.queue為空;
s.value<0時,s.value的絕對值為s.queue中等待進程的個數;
特性
編輯
抽象的來講,信號量的特性如下:信號量是一個非負整數(車位數),所有通過它的線程/進程(車輛)都會將該整數減一(通過它當然是為了使用資源),當該整數值為零時,所有試圖通過它的線程都將處於等待狀態。在信號量上我們定義兩種操作: Wait(等待) 和 Release(釋放)。當一個線程調用Wait操作時,它要麼得到資源然後將信號量減一,要麼一直等下去(指放入阻塞隊列),直到信號量大於等於一時。Release(釋放)實際上是在信號量上執行加操作,對應於車輛離開停車場,該操作之所以叫做「釋放」是因為釋放了由信號量守護的資源。
操作方式
編輯
對信號量有4種操作(include<semaphore>):
1. 初始化(initialize),也叫做建立(create) int sem_init(sem_t *sem, int pshared, unsigned int value);
2. 等信號(wait),也可叫做掛起(suspend)int sem_wait(sem_t *sem);
3. 給信號(signal)或發信號(post) int sem_post(sem_t *sem);
4.清理(destroy) int sem_destory(sem_t *sem);[1]
創建
編輯
同共享內存一樣,系統中同樣需要為信號量集定製一系列專有的操作函數(semget,semctl等)。系統命令ipcs可查看當前的系統IPC的狀態,在命令後使用-s參數。使用函數semget可以創建或者獲得一個信號量集ID,函數原型如下:
#include <sys/shm.h>
int semget( key_t key, int nsems, int flag);
函數中參數key用來變換成一個標識符,每一個IPC對象與一個key相對應。當新建一個共享內存段時,使用參數flag的相應許可權位對ipc_perm結構中的mode域賦值,對相應信號量集的shmid_ds初始化的值如表1所示。
shmid_ds結構初始化值表
ipc_perm結構數據
初 值
ipc_perm結構數據
初 值
Sem_otime
0
Sem_nsems
Nsems
Sem_ctime
系統當前值
參數nsems是一個大於等於0的值,用於指明該信號量集中可用資源數(在創建一個信號量時)。當打開一個已存在的信號量集時該參數值為0。函數執行成功,則返回信號量集的標識符(一個大於等於0的整數),失敗,則返回–1。函數semop用以操作一個信號量集,函數原型如下:
#include <sys/sem.h>
int semop( int semid, struct sembuf semoparray[], size_t nops );
函數中參數semid是一個通過semget函數返回的一個信號量標識符,參數nops標明了參數semoparray所指向數組中的元素個數。參數semoparray是一個struct sembuf結構類型的數組指針,結構sembuf來說明所要執行的操作,其定義如下:
struct sembuf{
unsigned short sem_num;
short sem_op;
short sem_flg;
}
在sembuf結構中,sem_num是相對應的信號量集中的某一個資源,所以其值是一個從0到相應的信號量集的資源總數(ipc_perm.sem_nsems)之間的整數。sem_op指明所要執行的操作,sem_flg說明函數semop的行為。sem_op的值是一個整數,如表2所示,列出了詳細sem_op的值及所對應的操作。
sem_op值詳解
Sem_op
操 作
正數
釋放相應的資源數,將sem_op的值加到信號量的值上
0
進程阻塞直到信號量的相應值為0,當信號量已經為0,函數立即返回。如果信號量的值不為0,則依據sem_flg的IPC_NOWAIT位決定函數動作。sem_flg指定IPC_NOWAIT,則semop函數出錯返回EAGAIN。sem_flg沒有指定IPC_NOWAIT,則將該信號量的semncnt值加1,然後進程掛起直到下述情況發生。信號量值為0,將信號量的semzcnt的值減1,函數semop成功返回;此信號量被刪除(只有超級用戶或創建用戶進程擁有此許可權),函數smeop出錯返回EIDRM;進程捕捉到信號,並從信號處理函數返回,在此情況將此信號量的semncnt值減1,函數semop出錯返回EINTR
負數
請求sem_op的絕對值的資源。如果相應的資源數可以滿足請求,則將該信號量的值減去sem_op的絕對值,函數成功返回。當相應的資源數不能滿足請求時,這個操作與sem_flg有關。sem_flg指定IPC_NOWAIT,則semop函數出錯返回EAGAIN。sem_flg沒有指定IPC_NOWAIT,則將該信號量的semncnt值加1,然後進程掛起直到下述情況發生:當相應的資源數可以滿足請求,該信號的值減去sem_op的絕對值。成功返回;此信號量被刪除(只有超級用戶或創建用戶進程擁有此許可權),函數smeop出錯返回EIDRM:進程捕捉到信號,並從信號處理函數返回,在此情況將此信號量的semncnt值減1,函數semop出錯返回EINTR
基本流程
編輯
下面實例演示了關於信號量操作的基本流程。程序中使用semget函數創建一個信號量集,並使用semop函數在這個信號集上執行了一次資源釋放操作。並在shell中使用命令查看系統IPC的狀態。
(1)在vi編輯器中編輯該程序。
程序清單14-10 create_sem.c 使用semget函數創建一個信號量
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int sem_id;
int nsems = 1;
int flags = 0666;
struct sembuf buf;
sem_id = semget(IPC_PRIVATE, nsems, flags); /*創建一個新的信號量集*/
if ( sem_id < 0 ){
perror( "semget ") ;
exit (1 );
}
/*輸出相應的信號量集標識符*/
printf ( "successfully created a semaphore : %d\n", sem_id );
buf.sem_num = 0; /*定義一個信號量操作*/
buf.sem_op = 1; /*執行釋放資源操作*/
buf.sem_flg = IPC_NOWAIT; /*定義semop函數的行為*/
if ( (semop( sem_id, &buf, nsems) ) < 0) { /*執行操作*/
perror ( "semop");
exit (1 );
}
system ( "ipcs -s " ); /*查看系統IPC狀態*/
exit ( 0 );
}
(2)在vmware中編譯該程序如下:
gcc -o a.o testc_semaphore.c
(3)在shell中運行該程序如下:
./a3.o
successfully created a semaphore : 0
------ Semaphore Arrays --------
key semid owner perms nsems
0x00000000 0 zcr 666 1
在上面程序中,用semget函數創建了一個信號量集,定義信號量集的資源數為1,接下來使用semop函數進行資源釋放操作。在程序的最後使用shell命令ipcs來查看系統IPC的狀態。
%注意:命令ipcs參數-s標識查看系統IPC的信號量集狀態。
希望能幫到你,滿意望採納哦。
『貳』 管程與信號量有什麼區別
管程的函數本身已經實現了互斥功能,而信號量要自己設計互斥
個人理解...
『叄』 linux下 進程信號量和線程信號量的區別和聯系是什麼
信號量在進程是以有名信號量進行通信的,在線程是以無名信號進行通信的,因為線程linux還沒有實現進程間的通信,所以在sem_init的第二個參數要為0,而且在多線程間的同步是可以通過有名信號量也可通過無名信號,但是一般情況線程的同步是無名信號量,無名信號量使用簡單,而且sem_t存儲在進程空間中,有名信號量必須LINUX內核管理,由內核結構struct ipc_ids 存儲,是隨內核持續的,系統關閉,信號量則刪除,當然也可以顯示刪除,通過系統調用刪除,
消息隊列,信號量,內存共享,這幾個都是一樣的原理。,只不過信號量分為有名與無名
『肆』 信號量是什麼有什麼區別使用信號量進行任務間通信有何優缺點
一:UCOS是一種搶占式的多任務操作系統,如果最高優先順序的任務不主動放棄CPU的使用的話內,其他任務是無容法運行的,通常情況下,高優先順序的任務在使用完CPU或其他資源後都要主動放棄,可以通過延時函數或者時等待一些信號量之類的讓自己掛起。但是如果最高優先順序任務一直使用CPU,那就跟單任務沒有什麼區別了。
二:可以通過等待信號量,消息等是當前任務掛起,或者通過通過延時函數將任務掛起,從而讓其他優先順序的任務運行。
UC/OS的信號量,消息隊列,郵箱的區別
信號量像一把鑰匙,任務要運行下去,需先拿到這把鑰匙。
消息郵箱是一個指針型變數。可以向一個任務或一個中斷服務子程序發送一則消息(一個指針),同樣,一個或多個任務通過內核服務,可以接收這則消息。消息郵箱也可以當作只取2個值的信號量來用。
消息隊列實際上是郵箱陣列。
『伍』 多線程中 信號和信號量分別定義是什麼
信號量在進程是以有名信號量進行通信的,在線程是以無名信號進行通信的,因為專線程linux還沒有實現屬進程間的通信,所以在sem_init的第二個參數要為0,而且在多線程間的同步是可以通過有名信號量也可通過無名信號,但是一般情況線程的同步是無名信號量,無名信號量使用簡單,而且sem_t存儲在進程空間中,有名信號量必須LINUX內核管理,由內核結構struct ipc_ids 存儲,是隨內核持續的,系統關閉,信號量則刪除,當然也可以顯示刪除,通過系統調用刪除,
消息隊列,信號量,內存共享,這幾個都是一樣的原理。,只不過信號量分為有名與無名
『陸』 操作系統中管程和信號量的區別
管程比信號量機抄制更安全 管程由系統襲來實現 而信號量的不足是 程序員對程序的不負責任 諸如用完資源不調用signal(),或者多信號量里 幾個wait()操作交換次序 等使得系統資源紊亂 所以產生了管程 由於我的老師只講了一點點 所以我對管程也不是太了解
『柒』 什麼是信號量
信號量(Semaphore)-- 相當一個信號燈,程序里是一個非負整數,表示狀態.
可以用來保護兩個或多個關鍵回代碼段,這些答關鍵代碼段不能並發調用。在進入一個關鍵代碼段之前,線程必須獲取一個信號量。如果關鍵代碼段中沒有任何線程,那麼線程會立即進入該框圖中的那個部分。一旦該關鍵代碼段完成了,那麼該線程必須釋放信號量。其它想進入該關鍵代碼段的線程必須等待直到第一個線程釋放信號量。為了完成這個過程,需要創建一個信號量,然後將Acquire Semaphore 以及Release Semaphore 分別放置在每個關鍵代碼段的首末端。確認這些信號量引用的是初始創建的信號量。
『捌』 操作系統 信號與信號量、管程實現同步互斥有什麼異同
操作系統中的信號指的是一個相對抽象的概念。信號量 sem 是指在利用版 P、V 原語編程時所需要對 sem 進行權的賦值操作(加 1 或者減 1 操作)。具體的例子你可以參照操作系統教材上的程序。進程的同步和互斥是操作系統中非常重要的概念。再具體的問題,你就得向教你操作系統的老師請教了。
『玖』 信號量P V操作,編程。兩隊伍過橋問題!
設信號量: MUTEX=1 (東西方復互斥制)
MD=1 (東向西使用計數變數互斥)
MX=1 (西向東使用計數變數互斥)
設整型變數: CD=0 (東向西的已上橋人數)
CX=0 (西向東的已上橋人數)
從東向西:
P (MD)
IF (CD=0)
{P (MUTEX) }
CD=CD+1
V (MD)
過橋
P (MD)
CD=CD-1
IF (CD=0)
{V (MUTEX) }
V (MD)
從西向東:
P (MX)
IF (CX=0)
{P (MUTEX) }
CX=CX+1
V (MX)
過橋
P (MX)
CX=CX-1
IF (CX=0)
{V (MUTEX) }
V (MX)
『拾』 信號量的基本流程
下面實例演示了關於信號量操作的基本流程。程序中使用semget函數創建一個信號量集,並使用semop函數在這個信號集上執行了一次資源釋放操作。並在shell中使用命令查看系統IPC的狀態。
(1)在vi編輯器中編輯該程序。
程序清單14-10 create_sem.c 使用semget函數創建一個信號量
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int sem_id;
int nsems = 1;
int flags = 0666;
struct sembuf buf;
sem_id = semget(IPC_PRIVATE, nsems, flags); /*創建一個新的信號量集*/
if ( sem_id < 0 ){
perror( semget ) ;
exit (1 );
}
/*輸出相應的信號量集標識符*/
printf ( successfully created a semaphore : %d
, sem_id );
buf.sem_num = 0; /*定義一個信號量操作*/
buf.sem_op = 1; /*執行釋放資源操作*/
buf.sem_flg = IPC_NOWAIT; /*定義semop函數的行為*/
if ( (semop( sem_id, &buf, nsems) ) < 0) { /*執行操作*/
perror ( semop);
exit (1 );
}
system ( ipcs -s ); /*查看系統IPC狀態*/
exit ( 0 );
}
(2)在vmware中編譯該程序如下:
gcc -o a.o testc_semaphore.c
(3)在shell中運行該程序如下:
./a3.o
successfully created a semaphore : 0
------ Semaphore Arrays --------key semid owner perms nsems 0x00000000 0 zcr 666 1 在上面程序中,用semget函數創建了一個信號量集,定義信號量集的資源數為1,接下來使用semop函數進行資源釋放操作。在程序的最後使用shell命令ipcs來查看系統IPC的狀態。
%注意:命令ipcs參數-s標識查看系統IPC的信號量集狀態。