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