进程通信之无名信号量
和有名信号量类似,无名信号也是进程之间/线程之间通信的主要手段,唯一不同的是他不能用在不同进程之间。当然如果把无名信号量放在多个进程都可以访问的共享内存里,也可以实现进程之间的通信,但这主要还是借助于共享内存的机制。下面将根据使用无名信号量依赖的头文件、需要链接的库文件、常用的函数分别进行介绍。
依赖头文件:#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()
{
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....
本文转自存储之厨51CTO博客,原文链接:http://blog.51cto.com/xiamachao/1791534 ,如需转载请自行联系原作者