當前位置:首頁 » 操作系統 » linuxc信號量

linuxc信號量

發布時間: 2022-03-11 23:24:35

linux C編程 信號量sys/sem 有等待超時么

可以用semtimedop

Ⅱ Linux信號 機制和Linux信號量機制的區別

首先,一句話總結它們之間的區別:

字面上相似,但是本質上存在巨大的差別!請看詳細解答...
Linux信號(signal) 機制

signal,又簡稱為信號(軟中斷信號)用來通知進程發生了非同步事件。

原理:

一個進程收到一個信號與處理器收到一個中斷請求可以說是一樣的。信號是進程間通信機制中唯一的非同步通信機制,一個進程不必通過任何操作來等待信號的到達,事實上,進程也不知道信號到底什麼時候到達。進程之間可以互相通過系統調用kill發送軟中斷信號。內核也可以因為內部事件而給進程發送信號,通知進程發生了某個事件。信號機制除了基本通知功能外,還可以傳遞附加信息。

分類:
從兩個不同的分類角度對信號進行:
可靠性方面:可靠信號與不可靠信號;
與時間的關繫上:實時信號與非實時信號。

部分定義轉自:http://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html

Linux信號量(semaphore)機制
Linux內核的信號量用來操作系統進程間同步訪問共享資源。

原理:信號量在創建時需要設置一個初始值,表示同時可以有幾個任務可以訪問該信號量保護的共享資源,初始值為1就變成互斥鎖(Mutex),即同時只能有一個任務可以訪問信號量保護的共享資源。
一個任務要想訪問共享資源,首先必須得到信號量,獲取信號量的操作將把信號量的值減1,若當前信號量的值為負數,表明無法獲得信號量,該任務必須掛起在該信號量的等待隊列等待該信號量可用;若當前信號量的值為非負數,表示可以獲得信號量,因而可以立刻訪問被該信號量保護的共享資源。
當任務訪問完被信號量保護的共享資源後,必須釋放信號量,釋放信號量通過把信號量的值加1實現,如果信號量的值為非正數,表明有任務等待當前信號量,因此它也喚醒所有等待該信號量的任務。

常用的信號量的API:

DECLARE_MUTEX(name)

該宏聲明一個信號量name並初始化它的值為0,即聲明一個互斥鎖。
DECLARE_MUTEX_LOCKED(name)

該宏聲明一個互斥鎖name,但把它的初始值設置為0,即鎖在創建時就處在已鎖狀態。因此對於這種鎖,一般是先釋放後獲得。
void sema_init (struct semaphore *sem, int val);

該函用於數初始化設置信號量的初值,它設置信號量sem的值為val。
void init_MUTEX (struct semaphore *sem);

該函數用於初始化一個互斥鎖,即它把信號量sem的值設置為1。
void init_MUTEX_LOCKED (struct semaphore *sem);

該函數也用於初始化一個互斥鎖,但它把信號量sem的值設置為0,即一開始就處在已鎖狀態。
void down(struct semaphore * sem);

該函數用於獲得信號量sem,它會導致睡眠,因此不能在中斷上下文(包括IRQ上下文和softirq上下文)使用該函數。該函數將把sem的值減1,如果信號量sem的值非負,就直接返回,否則調用者將被掛起,直到別的任務釋放該信號量才能繼續運行。
int down_interruptible(struct semaphore * sem);

該函數功能與down類似,不同之處為,down不會被信號(signal)打斷,但down_interruptible能被信號打斷,因此該函數有返回值來區分是正常返回還是被信號中斷,如果返回0,表示獲得信號量正常返回,如果被信號打斷,返回-EINTR。
int down_trylock(struct semaphore * sem);

該函數試著獲得信號量sem,如果能夠立刻獲得,它就獲得該信號量並返回0,否則,表示不能獲得信號量sem,返回值為非0值。因此,它不會導致調用者睡眠,可以在中斷上下文使用。
void up(struct semaphore * sem);

該函數釋放信號量sem,即把sem的值加1,如果sem的值為非正數,表明有任務等待該信號量,因此喚醒這些等待者。

實例:
信號量在絕大部分情況下作為互斥鎖使用,下面以console驅動系統為例說明信號量的使用。

在內核源碼樹的kernel/printk.c中,使用宏DECLARE_MUTEX聲明了一個互斥鎖console_sem,它用於保護console驅動列表console_drivers以及同步對整個console驅動系統的訪問。

Ⅲ linux進程間信號量的等待投遞

每個信號量都具有一個非負的值,且信號量支持等待和投遞操作。系統調用 semop 實現了這兩個操作。它的第一個參數是信號量的標識符,第二個參數是一個包含 struct sembuf 類型元素的數組;這些元素指明了您希望執行的操作。第三個參數是這個數組的長度。結構體sembuf中包含如下欄位:
sem_num將要執行操作的信號量組中包含的信號量數量。 sem_op是一個指定了操作類型的整數。 如果sem_op是一個正整數,則這個值會立刻被加到信號量的值上。 [BR]如果 sem_op 為負,則將從信號量值中減去它的絕對值。如果這將使信號量的值小於零,則這個操作會導致進程阻塞,直到信號量的值至少等於操作值的絕對值(由其它進程增加它的值)。 [BR]如果 sem_op 為0,這個操作會導致進程阻塞,直到信號量的值為零才恢復。 sem_flg 是一個符號位。指定 IPC_NOWAIT 以防止操作阻塞;如果該操作本應阻塞,則semop調用會失敗。如果為sem_flg指定SEM_UNDO,Linux會在進程退出的時候自動撤銷該次操作。 代碼 5.4 展示了二元信號量的等待和投遞操作。
代碼 5.4 (sem_pv.c)二元信號量等待和投遞操作
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/* 等待一個二元信號量。阻塞直到信號量的值為正,然後將其減1 */
int binary_semaphore_wait (int semid)
{
struct sembuf operations[1];
/* 使用(且僅使用)第一個信號量 */
operations[0].sem_num = 0;
/* 減一。 */
operations[0].sem_op = -1;
/* 允許撤銷操作 */
operations[0].sem_flg = SEM_UNDO;
return semop (semid, operations, 1);
}
/* 對一個二元信號量執行投遞操作:將其值加一。 這個操作會立即返回。*/
int binary_semaphore_post (int semid)
{
struct sembuf operations[1];
/* 使用(且僅使用)第一個信號量 */
operations[0].sem_num = 0;
/* 加一 */
operations[0].sem_op = 1;
/* 允許撤銷操作 */
operations[0].sem_flg = SEM_UNDO;
return semop (semid, operations, 1);
}
指定 SEM_UNDO 標志解決當出現一個進程仍然持有信號量資源時被終止這種特殊情況時可能出現的資源泄漏問題。當一個進程被有意識或者無意識地結束的時候,信號量的值會被調整到「撤銷」了所有該進程執行過的操作後的狀態。例如,如果一個進程在被殺死之前減小了一個信號量的值,則該信號量的值會增長。

Ⅳ linux 信號燈和信號量的區別

信號量是與signal相關的內容,是進程間通信的一種方式,一個進程可以向另一個進程發送一個信號作為通知,除了signal系統調用外,相關內容還有:

SEE ALSO
kill(1), alarm(2), kill(2), killpg(2), pause(2), sigaction(2), signalfd(2), sigpending(2), sigprocmask(2), sigsuspend(2), bsd_signal(3), raise(3), sigin-
terrupt(3), sigqueue(3), sigsetops(3), sigvec(3), sysv_signal(3), signal(7)

信號量也是進程通信的一種方式,一般用於並發取得資源對應鎖或者其他互斥操作,除了semget系統調用外,相關內容還有:

SEE ALSO
semctl(2), semop(2), ftok(3), capabilities(7), sem_overview(7), svipc(7)

Ⅳ linux +c 代碼 ,分別用posix共享內存+posix信號量,SystemV共享內存+SystemV信號量實現生產者和消費者例

挺簡單啊,信號+共享內存,這種例子很多啊

Ⅵ linux進程間信號量的初始信號

分配與初始化信號量是兩個相互獨立的操作。以 0 為第二參數,以 SETALL 為第三個參數調用 semctl 可以對一個信號量組進行初始化。第四個參數是一個 semun 對象,且它的 array 欄位指向一個 unsigned short數組。數組中的每個值均用於初始化該組中的一個信號量。
代碼 5.3 展示了初始化一個二元信號量的函數。
代碼 5.3 (sem_init.c) 初始化一個二元信號量
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/* 我們必須自己定義 union semun。*/
union semun
{
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
/* 將一個二元信號量初始化為 1。*/
int binary_semaphore_initialize (int semid)
{
union semun argument;
unsigned short values[1];
values[0] = 1;
argument.array = values;
return semctl (semid, 0, SETALL, argument);
}

Ⅶ linux下的Ctrl+C信號值是多少,該如何解決

Ctrl+C:送SIGINT信號,默認進程會結束,但是進程自己可以重定義收到這個信號的行為。 Ctrl+Z:送SIGSTOP信號,進程只是被停止,再送SIGCONT信號,進程繼續運行。 ctrl-d 不是發送信號,而是表示一個特殊的二進制值,表示 EOF 有些信號不能被屏蔽,比如中斷,還應該有殺死進程的信號,要不然內核怎麼做操作系統中的老大。實際上,SIGKILL和SIGSTOP信號是不能被屏蔽或阻止的,他們的默認動作總是會被執行的。

Ⅷ linux下 如何判斷信號量延時

/*編譯命令:gcc -o shm shm.c -g */
2
3#include<sys/sem.h>
4#include<sys/ipc.h>
5
6#define SEGSIZE 1024
7#define READTIME 1
8
9union semum
10{
11 int val;
12 struct semid_ds *buf;
13 unsigned short *array;
14}arg;
15
16/* 創建信號量 */
17int sem_creat(key_t key)
18{
19 union semun sem;
20 int semid;
21 sem.val = 0;
22 semid = semget(key, 1, IPC_CREAT | 0666);
23
24 if (semid == -1)
25 {
26 printf("Create semaphore error\n");
27 exit(-1);
28 }
29
30 semctl(semid, 0, SETVAL, sem);
31
32 return semid;
33}
34
35/* 刪除信號量*/
36int del_sem(int semid)
37{
38 union semun sem;
39 sem.val = 0;
40 semctl(semid, 0, IPC_RMID, sem);
41}
42
43/* 信號量的P操作,使得信號量的值加1 */
44int p(int semid)
45{
46 struct sembuf sops = {0,
47 +1,
48 IPC_NOWAIT
49 };
50
51 return (semop(semid, &sops, 1));
52}
53
54/* 信號量的v操作,使得信號量的值減1 */
55int v(int semid)
56{
57 struct sembuf sops = {0,
58 -1,
59 IPC_NOWAIT
60 };
61
62 return (semop(semid, &sops, 1));
63}
64
65/* server主程序 */
66int main(int argc, char **argv)
67{
68 key_t key;
69 int shmid, semid;
70 char *shm;
71 char msg[7] = "-data-";
72 char i;
73 struct semid_ds buf;
74
75 key = ftok("/", 0);
76 shmid = shmget(key, SEGSIZE, IPC_CREAT|0604);
77
78 if shmid == -1)
79 {
80 printf(" create shared memory error\n");
81 return -1;
82 }
83
84 shm = (char *)shmat(shmid, 0, 0);
85 if (-1 == (int)shm)
86 {
87 printf(" attach shared memory error\n");
88 return -1;
89 }
90
91 semid = sem_creat(key);
92
93 for (i = 0; i <= 3; i++)
94 {
95 sleep(1);
96 p(semid);
97 sleep(READTIME);
98 msg[5] = '0' + i;
99 memcpy(shm,msg,sizeof(msg));
100 sleep(58);
101 v(semid);
102 }
103
104 shmdt(shm);
105
106 shmctl(shmid,IPC_RMID,&buf);
107
108 del_sem(semid);
109
110 return 0;
111
112}
113
114
115
116
117
118
119
120
121

Ⅸ linux c 信號量與共享內存問題 多客戶端同時接受消息

假設伺服器的守護進程為D,D維護著一張廣播鏈表。假設鏈表元素為
struct BEntry{
pid_t pid; //伺服器子進程id
mqd_t mqd; //消息隊列描述符或者其他IPC手段也可以
};
每次有客戶端連上來,做fork的時候就把IPC手段建立好,不管用管道,或者消息,或者共享內存都大同小異,設客戶端連上來fork產生的伺服器子進程為Subn n為下標。

然後如果要廣播消息,就讓Subn通知D(可以用廣播鏈表裡的IPC手段,也可以另建),然後由D廣播消息給各個Subm, Subx,這些Sub進程再發給客戶端,這樣可以同時廣播,效率比較高。

Ⅹ linux常用信號量

  • linux的常用信號量

  1. BUS與SEGV
    二者都是錯誤信號,BUS表示匯流排錯誤,SEGV表示段錯誤,程序崩潰的時候99%都是這兩個錯誤導
    致的。進程可以捕獲和封鎖這兩類錯誤。內核對二者的默認處理是memory mp

  2. WINCH
    窗口改變信號(WINdown CHanged)。例如虛擬終端的行數發生變化時將發送WINCH信號,絕大多數
    文本編輯器都能捕獲WINCH信號自動進行重新配置。內核的默認處理是忽略該信號,並且不進行內存
    轉儲。
    進程可以捕獲或者封鎖該信號

  3. KILL
    殺死/刪除進程,編號為9

  4. STOP
    掛起/暫停正在執行的進程,直到收到CONT為止
    KILL STOP都不能夠被捕獲、封鎖或者忽略,默認處理都不會產生內存轉儲。

  5. CONT
    取消掛起,繼續執行進程

  6. TSTP
    是STOP信號的「軟」版本,即在用戶輸入Ctrl+Z時由終端驅動程序發送的信號。捕獲到該信號的進程通常
    清除它們的狀態,如何給自己發送一個STOP信號。TSTP的默認處理不會導致內存轉儲。

  7. INT
    中斷信號,編號為2
    當用戶輸入Ctrl+C時由終端驅動程序發送INT信號
    INT信號是終止當前操作的請求,簡單程序捕獲到INT信號時應該退出,擁有命令行或者輸入模式的那些
    程序應該停止他們正在做的事情,清除狀態,並等待用戶再次輸入。

  8. TERM
    軟體終止信號,編號為15
    TERM是請求徹底終止某項操作的信號,它期望進程清楚自己的狀態並退出

  9. QUIT
    退出信號,編號為3
    與TERM類似,不同之處在於QUIT信號的默認處理是內存轉儲,而TERM信號的默認處理沒有內存轉儲。

  10. HUP
    掛起信號,編號為1,有兩種解釋:
    守護進程理解HUP為重新設置的請求,如果守護進程能夠不用重新啟動就能夠重新讀取它自己的配置文
    件並調整自己以適應變化的話,那麼HUP信號通常可以用來觸發這種行為

  11. HUP
    信號有時有終端驅動程序生成,試圖用來清除(也就是終止)跟某個特定終端相連接的那些進程。例如
    當一個終端會話結束時,或者當一個Modem的連接不經意的斷開時,就可能出現這種情況。
    如果需要某些進程在會話結束之後繼續運行,那麼在C Shell中設法讓這些進程變成後台程序,
    ksh或者bash中可以用nohup來模擬這種行為。
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    進程的四種狀態

  12. runnable(可運行狀態)
    只要有CPU時間,進程就可以執行。一旦進程執行了不能立即完成的系統調用,Linux會把進程轉入
    睡眠狀態

  13. sleeping(睡眠狀態)
    進程在等待某些事件發生(如終端輸入、網路連接)

  14. zombie(僵化狀態)
    進程已經執行完畢並試圖消亡,但是狀態沒有收集完

  15. stopped(停止狀態)
    進程被掛起,不允許執行。進程收到STOP或者TSTP信號即進入停止狀態,可以用CONT信號來重新啟動

熱點內容
主流可編譯語言 發布:2024-11-15 00:42:23 瀏覽:729
excel緩存清除 發布:2024-11-15 00:39:53 瀏覽:486
機械鍵盤可編程 發布:2024-11-15 00:39:09 瀏覽:912
php判斷字元開頭 發布:2024-11-15 00:35:33 瀏覽:507
網易蘋果游戲怎麼轉移到安卓 發布:2024-11-15 00:07:52 瀏覽:270
win7php環境搭建 發布:2024-11-15 00:06:55 瀏覽:17
erpjava 發布:2024-11-14 23:52:23 瀏覽:253
電腦版地平線四怎麼連上伺服器 發布:2024-11-14 23:46:42 瀏覽:472
ios怎麼變安卓 發布:2024-11-14 23:46:36 瀏覽:333
win7共享xp列印機拒絕訪問 發布:2024-11-14 23:45:29 瀏覽:750