進程通訊之無名信號量

進程通訊之無名信號量less


    和有名信號量相似,無名信號也是進程之間/線程之間通訊的主要手段,惟一不一樣的是他不能用在不一樣進程之間。固然若是把無名信號量放在多個進程均可以訪問的共享內存裏,也能夠實現進程之間的通訊,但這主要仍是藉助於共享內存的機制。下面將根據使用無名信號量依賴的頭文件、須要連接的庫文件、經常使用的函數分別進行介紹。ide


依賴頭文件:#include <semaphore.h>函數


連接依賴庫: 須要連接到libpthread.so,所以makefile裏須要指定-lpthreadpost


重要函數列表:線程


int sem_init(sem_t *sem, int pshared, unsigned int value);指針

無名信號量的初始化函數,這個函數體現了無名信號量和有名信號量的主要區別,不一樣於有名信號量的初始化函數sem_open(),它不須要指定一個文件名,只須要傳遞一個進程、線程均可以訪問的信號量指針進去就能夠。若是須要在同一個進程的不一樣線程之間訪問,那麼pshared必須設置爲0,而且第一參數必須保證每一個線程均可以訪問;若是須要在不一樣進程間訪問,那麼pshared必須設置爲1,而且第一個參數必須放在共享內存區域。這個函數的地三個參數value指定了該信號量初始化的值,它表明系統剛開始可用的系統資源的個數。隊列

當上面的函數返回爲0時,表示函數調用成功;當返回爲-1的時候,表明出錯,錯誤代碼放在errno裏面,能夠經過strerror(errno)打印出來。進程



int sem_post(sem_t *sem);ip

unlock無名信號量,而且把可用的資源個數加1,喚醒等待當前信號量的線程或進程,讓被喚醒的進程或線程能夠拿到鎖。函數返回值同上。內存


int sem_wait(sem_t *sem);

int sem_trywait(sem_t *sem);

int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

上面的三個函數都能查詢當前有沒有可用資源,若是有:就搶到鎖並把當前可用的資源數目減1。若是沒有可用資源:不一樣的是sem_wait()會把當前進程或線程加入到休眠隊列,直到被喚醒;而sem_trywait()函數在系統沒有可用資源的狀況下會當即返回錯誤,並把錯誤代碼設置爲EAGAIN,當前進程或線程不會被阻塞;而sem_timewait()在沒有可用資源的狀況下,最長會被阻塞abs_timeout的時長,而後返回錯誤,並把錯誤代碼設置爲ETIMEDOUT。


int sem_getvalue(sem_t *sem, int *sval);

獲得當前信號量的值(表明當前系統可用資源的數量),並把它放到sval指向的內存裏面。



代碼示例

#include <stdio.h>

#include <stdint.h>

#include <stdlib.h>

#include <string.h>

#include <assert.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>


#include <fcntl.h>           /* For O_* constants */

#include <sys/stat.h>        /* For mode constants */

#include <semaphore.h>

#include <errno.h>


sem_t clnt_sem;

int create_done = 0;


void state_thread1()

{

while(1) {

if (!create_done) continue;

printf("%s: Wait semp....\n", __FUNCTION__);

sem_wait(&clnt_sem);

printf("%s: Wait semp done: semp comes\n",  __FUNCTION__);

}

}


void state_thread2()

{

while(1) {

printf("%s: Wait semp....\n", __FUNCTION__);

sem_wait(&clnt_sem);

printf("%s: Wait semp done: semp comes\n",  __FUNCTION__);

sleep(10);

}

}



void main(void)

{

pthread_t ftids;

int ret;


ret = sem_init(&clnt_sem,0, 3);

if (ret < 0) {

printf("%s\n", strerror(errno));

}


pthread_create(&ftids, NULL, (void *)state_thread1, NULL);

pthread_create(&ftids, NULL, (void *)state_thread2, NULL);

create_done = 1;

sem_post(&clnt_sem);


while(1) {

printf("IN Clnt main process\n");

sleep(10);

}


編譯和運行結果:

[xqch@localhost testcases]$ gcc -o sem_nameless sem_nameless.c -lpthread

[xqch@localhost testcases]$ ./sem_nameless

IN Clnt main process

state_thread2: Wait semp....

state_thread2: Wait semp done: semp comes

state_thread1: Wait semp....

state_thread1: Wait semp done: semp comes

state_thread1: Wait semp....

state_thread1: Wait semp done: semp comes

state_thread1: Wait semp....

state_thread1: Wait semp done: semp comes

state_thread1: Wait semp....

IN Clnt main process

state_thread2: Wait semp....

相關文章
相關標籤/搜索