生活随笔
收集整理的這篇文章主要介紹了
Linux信号量详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Linux信號量詳解
1.什么是信號量 信號量是一種特殊的變量,訪問具有原子性。 只允許對它進行兩個操作:1)等待信號量 當信號量值為0時,程序等待;當信號量值大于0時,信號量減1,程序繼續運行。2)發送信號量 將信號量值加1。
我們使用信號量,來解決進程或線程間共享資源引發的同步問題。
2.Linux中信號量的使用 Linux提供了一組信號量API,聲明在頭文件sys/sem.h中。1)semget函數:新建信號量
int semget(key_t key,
int num_sems,
int sem_flags);
key:信號量鍵值,可以理解為信號量的唯一性標記。 num_sems:信號量的數目,一般為1 sem_flags:有兩個值,IPC_CREATE和IPC_EXCL,IPC_CREATE表示若信號量已存在,返回該信號量標識符。 IPC_EXCL表示若信號量已存在,返回錯誤。 返回值:相應的信號量標識符,失敗返回-1
2)semop函數:修改信號量的值
int semop(
int sem_id,
struct sembuf *sem_opa,size_t num_sem_ops);
sem_id:信號量標識符 sem_opa:結構如下
struct sembuf{ short sem_num;
// 除非使用一組信號量,否則它為0 short sem_op;
// 信號量在一次操作中需要改變的數據,通常是兩個數,一個是-1,即P(等待)操作, // 一個是+1,即V(發送信號)操作。 short sem_flg;
// 通常為SEM_UNDO,使操作系統跟蹤信號, // 并在進程沒有釋放該信號量而終止時,操作系統釋放信號量
};
3)semctl函數:用于信號量的初始化和刪除
int semctl(
int sem_id,
int sem_num,
int command,[union semun sem_union]);
command:有兩個值SETVAL,IPC_RMID,分別表示初始化和刪除信號量。 sem_union:可選參數,結構如下:
union semun{ int val; struct semid_ds *
buf; unsigned short *
arry;
}; 一般用到的是val,表示要傳給信號量的初始值。
3.Linux信號量使用示例 下例中,我們寫了一個程序,程序中有一個char類型的字符,char message='x' 然后同時運行這個程序的兩個實例。 第一個實例,帶一個參數,將參數的第一個字符賦給message,比如為'0' 第二個實例,使用默認message值'x' 我們的目的是,使用信號量,循環執行這兩個實例, 我們可以看到執行結果應該是'x0x0x0x0x0x0'
#include<stdio.h>
#include <stdlib.h>
#include <sys/sem.h>
union semun
{ int val; struct semid_ds *
buf;unsigned short *
array;
};
int sem_id;
int set_semvalue()
{union semun sem_union; sem_union.val =
1 ; if (semctl(sem_id,
0 ,SETVAL,sem_union)==-
1 ) return 0 ; return 1 ;
}
int semaphore_p()
{ struct sembuf sem_b;sem_b.sem_num =
0 ;sem_b.sem_op = -
1 ;sem_b.sem_flg =
SEM_UNDO; if (semop(sem_id,&sem_b,
1 )==-
1 ){fprintf(stderr, " semaphore_p failed\n " ); return 0 ;} return 1 ;
}
int semaphore_v()
{ struct sembuf sem_b;sem_b.sem_num =
0 ;sem_b.sem_op =
1 ;sem_b.sem_flg =
SEM_UNDO; if (semop(sem_id,&sem_b,
1 )==-
1 ){fprintf(stderr, " semaphore_v failed\n " ); return 0 ;} return 1 ;
}
void del_semvalue()
{ // 刪除信號量
union semun sem_union; if (semctl(sem_id,
0 ,IPC_RMID,sem_union)==-
1 )fprintf(stderr, " Failed to delete semaphore\n " );
}
int main(
int argc,
char *
argv[])
{ char message =
' x ' ; // 創建信號量 sem_id = semget((key_t)
1234 ,
1 ,
0666 |
IPC_CREAT); if (argc>
1 ){ // 初始化信號量 if (!
set_semvalue()){fprintf(stderr, " init failed\n " );exit(EXIT_FAILURE);} // 參數的第一個字符賦給message message = argv[
1 ][
0 ];} int i=
0 ; for (i=
0 ;i<
5 ;i++
){ // 等待信號量 if (!
semaphore_p())exit(EXIT_FAILURE);printf( " %c " ,message);fflush(stdout);sleep( 1 ); // 發送信號量 if (!
semaphore_v())exit(EXIT_FAILURE);sleep( 1 );}printf( " \n%d-finished\n " ,getpid()); if (argc>
1 ){ // 退出前刪除信號量
del_semvalue();}exit(EXIT_SUCCESS);
} 輸出結果:
總結
以上是生活随笔 為你收集整理的Linux信号量详解 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。