信号量是进化版的互斥锁(互斥锁,加锁后由1变为0就会阻塞,而信号量是由N变成N--,只要不是0,就不会阻塞)
N等于1的话,信号量就与互斥锁等价了。
互斥锁的粒度比较大,无法在多个线程间对某一对象的部分数据进行共享,降低了线程的并发性,信号量可以解决这个问题
1、信号量常用的函数(函数前缀没有pthread,故信号量也可以用于进程同步)
#include <semaphore.h>
1)sem_init
pshared:=0,用于线程间同步;
pshared>0,用于进程间同步。
2)sem_destroy//有init就对应有destroy.
3)sem_wait//相当于pthread_mutex_lock;N--
4)sem_trywait
5)sem_post//相当于pthread_mutex_unlock;N++
信号量大于0,则信号量--
信号量等于0,则造成线程阻塞。
信号量的初值,决定了占用信号量线程的个数。
2、信号量生产者和消费者模型
定义两个信号量sem_productor、sem_t sem_blank;
生产者
产品数:sem_productor;
sem_wait(&sem_blank);//N-- //想象成停车位,等到车位了,剩余车位-1(信号量-1)
sem_post(&sem_productor);//N++ //想象成停车位,车离开车位了,剩余车位+1(信号量+1)
消费者:
空格数sem_t sem_blank;
sem_wait(&sem_productor);//N--
sem_post(&sem_blank);//N++
#inlcude <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <semphore.h>
#define NUM 5
sem_t product_number,blank_number;
int queue[NUM];
void *productor(void*arg)
{
int i =0;
while(1)
{
sem_wait(&blank_number);//空格子数--,为0阻塞
queue[i] = rand()%1000+1;
printf("productor%d",queue[i]);
sem_post(&product_number);//产品数++
i = (i+1)%NUM;//实现环形队列
sleep(rand()%3);
}
}
void *consumer(void*arg)
{
int i =0;
while(1)
{
sem_wait(&product_number);
queue[i] = 0;
printf("consumer%d",queue[i]);
sem_post(&blank_number);
i = (i+1)%NUM;
sleep(rand()%3);
}
}
void main()
{
sem_init(&product_number,0,0);//初始化产品数为0
sem_init(&blank_number,0,NUM);//初始化空格为5
pthread_t pthread_p,pthread_c;
pthread_create(&pthread_p,NULL,productor,NULL);
pthread_create(&pthread_c,NULL,consumer,NULL);
pthread_join(pthread_p,NULL);
pthread_join(pthread_c,NULL);
sem_destroy(&product_number);
sem_destroy(&blank_number);
}