linux c++(线程 & 信号量 & 生产者消费者模型)
生产者和消费者模型
信号量[加强版的互斥锁]
- int sem_init(setm_t *sem,int pshared,unsigned int valud);
- sem 定义的信号量,传出
- pshared
- 0 代表线程信号量
- 非0 代表进程信号量
- value 定义信号量的个数
- 摧毁信号量
- int sem_destory(sem_t *sem);
- 申请信号量,申请成功 value--
- int sem_wait(sem_t *sem);- 信号量为0时,阻塞
- 释放信号量value++
- int sem_post(sem_t *sem);
#include <semaphore.h>
sem_t blank,xfull;
#define __SEM_CNT__ 5
int queue[__SEM_CNT__];
int beginnum = 100;
✹ void * thr_producter(void *arg)
{
int i = 0;
while(1)
{
sem_wait(&blank);//申请资源 blank--
printf("----%s----self---%lu----%d\n",__FUNCTION__,pthread_self(),beginnum
queue[(i++)%__SEM_CNT__] = beginnum++;
sem_post(&xfull);//xfull ++
sleep(rand()%3);
}
pthread_exit(NULL);
}
// 创建线程 #include <pthread.h>
✹ void * thr_custmer(void *arg)
{
int i = 0,num = 0;
while(1)
{
sem_wait(&xfull);
num = queue[(i++)%__SEM_CNT__];
printf("----%s----self---%lu----%d\n",__FUNCTION__,pthread_self(),num);
sem_post(&blank);
sleep(rand()%3);
}
pthread_exit(NULL);
}
int main()
{
sem_init(&blank,0,__SEM_CNT__);
sem_init(&xfull,0,0);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_t tid[2];
pthread_create(&tid[0],&attr,thr_producter,NULL);
pthread_create(&tid[1],&attr,thr_custmer,NULL);
pthread_attr_destroy(&attr);
pthread_exit(NULL);
sem_destroy(&blank);
sem_destroy(&xfull);
return 0;
}
信号量就是在一个叫做互斥区的门口放一个盒子,盒子里面装着固定数量的小球,每个线程过来的时候,都从盒子里面摸走一个小球,然后去互斥区里面浪(?),浪开心了出来的时候,再把小球放回盒子里。如果一个线程走过来一摸盒子,得,一个球都没了,不拿球不让进啊,那就只能站在门口等一个线程出来放回来一个球,再进去。这样由于小球的数量是固定的,那么互斥区里面的最大线程数量就是固定的,不会出现一下进去太多线程把互斥区给挤爆了的情况。这是用信号量做并发量限制。
另外一些情况下,小球是一次性的,线程拿走一个进了门,就把小球扔掉了,这样用着用着小球就没了,不过有另外一些线程(一般叫做生产者)会时不时过来往盒子里再放几个球,这样就可以有新的线程(一般叫做消费者)进去了,放一个球进一个线程,这是信号量做同步功能。你截图里的例子就是这个情况,主线程是生产者,通过sem_post往盒子里放小球(信号量加一),而其他线程是消费者,通过sem_wait从盒子里拿小球(信号量减一),如果遇到盒子里一个小球都没有(信号量为0),就会开始等待信号量不为0,然后拿走一个小球(信号量减一)再继续。
本质上来说信号量就是那个盒子,以及“摸不到球就不让进”这个机制。
顺便你这个例子其实有点问题,发送信号量也就是放小球的这个过程并不会阻塞,会继续执行下去,那么有可能在消费者线程取走work_area里面的数据之前,下一个fgets就把这个数据覆盖了,这是个很危险的竞争冒险的问题,非常不符合多线程程序的设计准则。由于是从stdin当中读取数据,一般来说键盘是没有这么快,但要知道完全可以把输入重定向到文件,这时候就很容易出问题了
浙公网安备 33010602011771号