在前面的进程控制里面我们说到了System V版本的信号量,主要用于进程控制。同样,线程控制里面也有相应的信号量,它用于线程间同步,就是我们下面要讲的Posix信号量
说到信号量,我们都明白,信号量就相当于一个计数器,它的目的是为了保护临界资源,通过信号量的P,V操作,就可以对临界资源的数目进行修改
POSIX信号量
初始化信号量
#include<semaphore.h>
int sem_init(seq_t *sem,int pshared,unsifned int value);
参数:
pshared:0表示线程间共享,非零表示进程间共享
value:信号量的初始值
销毁信号量
int sem_destroy(sem_t *sem);
等待信号量
功能:等待信号量, 将信号量的值减一
int sem_wait(sem_t *sem);
发布信号量
功能:发布信号量,表示资源使用完毕,可以归还资源了,将信号量值加一
int sem_post(sem_t *sem);
接下来我们通过一个具体的例子了解信号量的作用
消费者与生产者模型
消费者和生产者我们都知道
生产者生产后放到仓库,消费者拿去消费
那么问题来了!!!
当生产者生产的慢,消费者比较多的时候,就会出现,消费者一直申请锁释放锁,线程死锁问题,
如果是消费者慢,生产者快,那么在一个环状结构中,生产者生产的新的数据就会把之前的数据覆盖掉产生严重的后果
下面先看一个没有信号量的
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define CONSUMERS_COUNT 2
#define PRODUCERS_COUNT 2
struct msg{
struct msg *next;
int num;
};
struct msg *head = NULL;
pthread_cond_t cond;
pthread_mutex_t mutex;
pthread_t threads[CONSUMERS_COUNT + PRODUCERS_COUNT];
void *consumer(void *p)
{
int num = *(int *)p;
free(p);
struct msg *mp;
for(;;){
pthread_mutex_lock(&mutex);
while(head == NULL)
{
printf("%d begin wait a condition...\n",num);
pthread_cond_wait(&cond,&mutex);
}
printf("