如同进程一样,线程也可以通过信号量来实现通信,虽然是轻量级的。
信号量函数的名字都以"sem_"打头。线程使用的基本信号量函数有四个。
#include <semaphore.h>
int sem_init (sem_t *sem , int pshared, unsigned int value);
这是对由sem指定的信号量进行初始化,设置好它的共享选项(linux 只支持为0,即表示它是当前进程的局部信号量),然后给它一个初始值VALUE。
两个原子操作函数:
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
这两个函数都要用一个由sem_init调用初始化的信号量对象的指针做参数。
sem_post:给信号量的值加1;
sem_wait:给信号量减1;对一个值为0的信号量调用sem_wait,这个函数将会等待直到有其它线程使它不再是0为止。
int sem_destroy(sem_t *sem);
这个函数的作用是再我们用完信号量后都它进行清理。归还自己占有的一切资源。
<span style="font-size:18px;">#include "stdio.h"
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define N_CONSUMER 3 //消费者数量
#define N_PRODUCER 2 //生产者数量
#define C_SLEEP 1 //控制 consumer 消费的节奏
#define P_SLEEP 1 //控制 producer 生产的节奏
pthread_mutex_t mutex;
pthread_cond_t condp,condc;
int cnt=0;//缓冲区当前的产品数
const int MAX=4;//缓冲区大小
sem_t full;
sem_t empty;
int buffer[10];
void * produce(void * arg)
{
<span style="white-space:pre"> </span>while(1)
{
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>sem_wait(&empty);
<span style="white-space:pre"> </span>pthread_mutex_lock(&mutex);
<span style="white-space:pre"> </span>printf("produce :");
<span style="white-space:pre"> </span>cnt++;
<span style="white-space:pre"> </span>printf("cnt= %d\n",cnt);
<span style="white-space:pre"> </span>sem_post(&full);
<span style="white-space:pre"> </span>pthread_mutex_unlock(&mutex);
<span style="white-space:pre"> </span>sleep(2);
}
<span style="white-space:pre"> </span>return 0;
}
void * consume(void * arg)
{
while(1)
{
<span style="white-space:pre"> </span>sem_wait(&full);
<span style="white-space:pre"> </span>pthread_mutex_lock(&mutex);
<span style="white-space:pre"> </span>printf("consume :");
<span style="white-space:pre"> </span>cnt--;
<span style="white-space:pre"> </span>printf("cnt= %d\n",cnt);
<span style="white-space:pre"> </span>sem_post(&empty);
<span style="white-space:pre"> </span>pthread_mutex_unlock(&mutex);
<span style="white-space:pre"> </span>sleep(1);
<span style="white-space:pre"> </span>
}
<span style="white-space:pre"> </span>return 0;
}
int main()
{
<span style="white-space:pre"> </span>pthread_t ptid,ctid;
<span style="white-space:pre"> </span>pthread_mutex_init(&mutex,NULL);
<span style="white-space:pre"> </span>sem_init(&full,0,0);
<span style="white-space:pre"> </span>sem_init(&empty,0,MAX);
<span style="white-space:pre"> </span>pthread_create(&ptid,NULL,produce,NULL);
<span style="white-space:pre"> </span>pthread_create(&ctid,NULL,consume,NULL);
<span style="white-space:pre"> </span>sleep(100);
<span style="white-space:pre"> </span>pthread_mutex_destroy(&mutex);
<span style="white-space:pre"> </span>sem_destroy(&full);
<span style="white-space:pre"> </span>sem_destroy(&empty);
<span style="white-space:pre"> </span>return 0;
}</span>