进程通讯之无名信号量

进程通讯之无名信号量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....

相关文章
相关标签/搜索