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