程序通信之無名信号量
和有名信号量類似,無名信号也是程序之間/線程之間通信的主要手段,唯一不同的是他不能用在不同程序之間。當然如果把無名信号量放在多個程序都可以通路的共享記憶體裡,也可以實作程序之間的通信,但這主要還是借助于共享記憶體的機制。下面将根據使用無名信号量依賴的頭檔案、需要連結的庫檔案、常用的函數分别進行介紹。
依賴頭檔案:#include <semaphore.h>
連結依賴庫: 需要連結到libpthread.so,是以makefile裡需要指定-lpthread
重要函數清單:
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);
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()
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);
printf("IN Clnt main process\n");
編譯和運作結果:
[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
本文轉自存儲之廚51CTO部落格,原文連結:http://blog.51cto.com/xiamachao/1791534 ,如需轉載請自行聯系原作者