信号量
信号量,是相对折中的一种处理方式,既能保证同步,数据不混乱,又能提高线程并发。
由于互斥锁的粒度比较大,如果我们希望在多个线程间对某- -对象的部分数据进行共享,使用互斥锁是
没有办法实现的,只能将整个数据对象锁住。这样虽然达到了多线程操作共享数据时保证数据正确性的
目的,却无形中导致线程的并发性下降。线程从并行执行,变成了串行执行。与直接使用单进程无异。
主要函数
sem. init 函数
sem_ destroy函数
sem. _wait 函数
sem_ trywait 函数
sem. timedwait函数
sem. post函数
以上6个函数的返回值都是:成功返回0,失败返回-1,同时设置errng。 (注意, 它们没有pthread前缀)
sem_ .t类型,本质仍是结构体。但应用期间可简单看作为整数,忽略实现细节(类似于使用文件描述符)。
sem_ .tsem;规定信号量sem不能<0
头文件<semaphore.h>
信号量基本操作
sem_wait:
1.信号量大于0,则信号量-- (类比pthread_mutex_lock)
2.信号量等于0时,再次调用会造成线程阻塞。
对应
sem_post:
将信号量++,同时唤醒阻塞在信号量上的线程(类比pthread_mutex_unlock)
但是由于sem的实现对用户隐藏,所以所谓的++,--操作只能通过函数来实现,而不能直接++,,符号信号量的初值,决定了占用信号量线程的个数。
sem destroy函数
销毁信号量
int sen_destroy(sem_t *sem);
sem_ wait函数
信号量减减操作(类似加锁)
int sem_ wait(sen. t *sem);
sem_ post函数
信号量加加操作(类似解锁)
int sem_ post(sen _t *sem);
例程:利用信号操作实现生产消费者模型
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#define NUM 100
int queue[NUM];
sem_t blank_number,product_number,product_number2;
void *producer(void *arg)
{
while(1)
{
sem_wait(&blank_number);
sem_post(&product_number);
i=(i+2)%NUM;
sleep(2);
}
}
void *producer02(void *arg)
{
sleep(2);
{
sem_wait(&blank_number);
queue[i]=rand()%1000+2;
sem_post(&product_number2);
i=(i+1)%NUM;
sleep(2);
}
}
void *consumer(void *arg)
{
int i=0;
{
sleep(1);
sem_wait(&product_number2);
queue[i]=0;
sem_post(&blank_number);
i=(i+1)%NUM;
}
}
//void *consumer02(void *arg)
//{
// int i=1;
// sleep(1);
// while(1)
// {
// sleep(2);
// sem_wait(&product_number);
// queue[i]=0;
// sem_post(&blank_number);
// i=(i+2)%NUM;
// }
//}
int main(int argc,char *argv[])
{
pthread_t pid[2],cid[2];
sem_init(&blank_number,0,NUM);
sem_init(&product_number,0,0);
sem_init(&product_number2,0,0);
pthread_create(&pid[0],NULL,producer,NULL);
pthread_create(&pid[1],NULL,producer02,NULL);
pthread_create(&cid[0],NULL,consumer,NULL);
// pthread_create(&cid[1],NULL,consumer02,NULL);
pthread_join(pid[0],NULL);
pthread_join(pid[1],NULL);
pthread_join(cid[0],NULL);
// pthread_join(cid[1],NULL);
sem_destroy(&blank_number);
sem_destroy(&product_number);
sem_destroy(&product_number2);
return 0;
}
此程序为两个生产者,一个消费者