微吼云上線多路互動直播服務 加速多場景互動直播落地
655
2025-04-02
信號量是什么
信號量是一種計數器,用來控制對多個進程/線程共享的資源進行訪問。常和鎖一同使用。
在某個進程/線程正在對某個資源進行訪問時,信號量可以阻止另一個進程/線程去打擾。
生產者和消費者模型是信號量的典型使用。
為什么信號量分兩套(兩套有什么區別)
簡要的說,Posix是“可移植操作系統接口(Portable Operating System Interface )的首字母簡寫,但它并不是一個單一的標準,而是一個電氣與電子工程學會即IEEE開發的一系列標準,它還是由ISO(國際標準化組織)和IEC(國際電工委員會)采納的國際標準。而System v是Unix操作系統眾多版本的一個分支,它最初是由AT&T在1983年第一次發布,System v一共有四個版本,而最成功的是System V Release 4,或者稱為SVR4。這樣看來,一個是Unix 的標準之一(另一個標準是Open Group),一個是Unix眾多版本的分支之一(其他的分支還有Linux跟BSD),應該來說,Posix標準正變得越來越流行,很多廠家開始采用這一標準。
那么兩者有什么區別,或者說,應用場景:
1、POSIX信號量常用于線程;system v信號量常用于進程的同步。
2、從使用的角度,System V 信號量的使用比較復雜,而 POSIX 信號量使用起來相對簡單。
3、對 POSIX 來說,信號量是個非負整數。而 System V 信號量則是一個或多個信號量的集合,它對應的是一個信號量結構體,這個結構體是為 System V IPC 服務的,信號量只不過是它的一部分。
4、Posix信號量是基于內存的,即信號量值是放在共享內存中的,它是由可能與文件系統中的路徑名對應的名字來標識的。而System v信號量則是基于內核的,它放在內核里面。
5、POSIX 信號量的頭文件是
6、Posix還有有名信號量,一般用于進程同步, 有名信號量是內核持續的。
怎么實現呢?
1、新建信號量
system V
#include
1
2
3
4
5
6
7
8
9
利用System V函數包裝建立信號量的代碼;
typedef int sem_t; union semun { int val; struct semid_ds *buf; //semid_ds的指針 unsigned short *array; //數組類型 } arg; //定義一個全局變量 sem_t CreateSem(key_t key,int value) { union semun sem; //信號量結構變量 sem_t sem_id; sem.val = value; //設置初始值 sem_id = semget(key,0,IPC_CREAT|0666); //獲取信號量id if(sem_id == -1) { printf("create sem failed\n"); exit(-1); } semctl(sem_id,0,SETVAL,sem); //發送命令,建立value個初始信號量 return sem_id; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Posix信號量:直接用那個函數就好了,可以加一個報錯保險。
【后面的栗子都一樣,Posix就這么簡單】
2、PV操作(增減信號量)
System V
/* 參數釋義: struct sembuf { ushort sem_num; //信號量的編號 short sem_op; //信號量的操作 {正負零} short sem_flg; //信號量的操作標志 {NOWAIT} }; //sem_op取0表示將信號量設為睡眠狀態,直到信號量的值為0為止 nsops:該數組中操作的個數 */
1
2
3
4
5
6
7
8
9
10
11
12
int Sem_P(sem_t semid) { struct sembuf sops = {0,+1,IPC_NOWAIT}; return (semop(semid,&sops,1)); }
1
2
3
4
5
intSem_V(sem_t semid) { struct sembuf sops = {0,-1,IPC_NOWAIT}; return (semop(semid,&sops,1)); }
1
2
3
4
5
P操作:進行增加一個信號量的值的操作
V操作:進行減少一個信號量的值的操作
Posix
P:sem_post(sem_t *sem);
V:sem_wait(sem_t *sem);
3、控制信號量參數
#include
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//栗子就不放了
4、銷毀信號量
System V
void DestroySem(sem_t semid) { union semun sem; sem.val = 0; se,ctl(semid,0,IPC_RMID,sem); }
1
2
3
4
5
6
最后,放一串生產消費者的代碼
//實現線程互斥 #include
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。