定义:
如果有一个任务试图获得已经被占用的信号量时,信号量会将其推进一个等待队列,使其睡眠,当持有信号量的进程将信号量释放以后,再唤醒该任务,并获得该信号量。
头文件head.h代码:
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#endif
sem.c代码:
#include "head.h"
sem_t sem_w;
sem_t sem_r;
int a = 0;
void *eat0(int *arg)
{
while(1)
{
sem_wait(&sem_w);
printf("[1]:wochiledi %2d wanfan!\n",++a);
usleep(500000);
sem_post(&sem_r);
}
}
void *eat1(int *arg)
{
while(1)
{
sem_wait(&sem_r);
printf("[2]:wochiledi %2d wanfan\n",++a);
usleep(500000);
sem_post(&sem_w);
}
}
void main(int argc ,char *argv[])
{
int ret;
pthread_t pid0,pid1;
sem_init(&sem_r,0,0); //参数二设置为0用于进程内多线程共享,参数三表示可用资源的数目,即信号灯的数目
sem_init(&sem_w,0,1);
if( 0 != pthread_create(&pid0,NULL,eat0,NULL)) //创建线程1
{
printf("fail to create pthread0!\n");
exit(-1);
}
if( 0 != pthread_create(&pid1,NULL,eat1,NULL)) //创建线程2
{
printf("fail to create pthread1!\n");
exit(-1);
}
if( 0 != pthread_join(pid0,NULL)) //以阻塞方式等待线程1结束
{
printf("fail to join the pthread!\n");
exit(-1);
}
if( 0 != pthread_join(pid1,NULL)) //以阻塞方式等待线程2结束
{
printf("fail to join the pthread!\n");
exit(-1);
}
}
编译程序:
gcc -o sem sem.c -pthread
./sem
结果:
总结:
主函数创建两个线程,信号量初始化资源设置为1,线程调用sem_wait取获取这个信号灯,第一个线程一看,有1个,他就拿到了,然后可以继续后继操作,此时信号灯自动减1,变成0个。那么第二个线程调用sem_wait时就会阻塞在这儿了。第一个线程完成打印后,调用sem_post释放信号灯,信号灯数目变成1,将会唤醒等待的第二个线程,然后第二个线程接着打印。最后当所有任务完成后,主线程调用sem_destroy释放这个信号量。