您的位置:首页 > 其它

多线程之生产者消费者模型

2017-05-17 12:10 232 查看
1、描述一下生产者消费者模型。

有n个生产者线程生产产品,m个消费者线程消费产品。在这里他们需要互斥地访问产品。

2、为什么要把产品数量设入临界区,如何实现临界区的(如何调用相关API)?

因为如果在资源抢占过程中,恢复现场时会覆盖另一个线程对产品数量的操作结果。

在Linux下,调用pthread_mutex_lock(&mutex)和pthread_mutex_unlock(&mutex)对临界区加锁解锁。

3、在临界区内是如何避免死锁的。并请你深入操作系统内核层面剖析一下其中原理。

定义产品数量为g_num一个消费者进程进入临界区后

if(g_num == 0){丢弃锁}

线程通过调用pthread_cond_wait(&g_cond, &g_mutex)来进行丢弃锁。

在调用pthread_cond_wait()后,操作系统做了三件事情。

第一步线程丢锁,然后线程休眠,第三步线程等待苏醒。线程需要用另一个API来唤醒。thread_cond_signal()。

4、请编码实现生产者消费者模型。并将产品数量控制在20以内。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#define CUSTOMER_COUNT 2
#define PRODUCTER_COUNT 4
int g_num = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//定义锁
pthread_cond_t my_condition = PTHREAD_COND_INITIALIZER;//定义条件并初始化
void* customer(void* arg)//消费者线程
{
int inum = 0;
inum = *(int *)arg;
while (1)
{
pthread_mutex_lock(&mutex); //线程获得锁,进入临界区
printf("cumstomer:%d\n", inum);
while (g_num == 0)
{
printf("\nwaiting start\n");
pthread_cond_wait(&my_condition, &mutex);//条件锁
printf("waiting end\n");
}
printf("customer run\n");
g_num--;//消费产品
printf("customer end\n");
pthread_mutex_unlock(&mutex);//线程释放锁,退出临界区
sleep(1);
}
pthread_exit(0);
}

void* producter(void* arg)//生产者线程
{
int inum = 0;
inum = *(int *)arg;
while (1)
{
pthread_mutex_lock(&mutex);//线程获得锁,创建临界区,判断产品数量
if (g_num > 20)
{
printf("Product:%d too much.\n", g_num);
pthread_mutex_unlock(&mutex);
sleep(1);
continue;
}
else
{
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex);//获得锁,进入临界区
printf("producter:%d\n", inum);
printf("The num of g_num:%d\n", g_num);
printf("producter run\n");
g_num++;//生产产品
printf("producter end\n");
pthread_cond_signal(&my_condition);//产出产品,唤醒等待线程
pthread_mutex_unlock(&mutex);//释放锁,退出临界区
sleep(1);
}
pthread_exit(0);
}
int main()
{
int i = 0;
pthread_t threadArray[CUSTOMER_COUNT + PRODUCTER_COUNT + 10];//线程数组

for (i = 0; i < PRODUCTER_COUNT; i++)//创建生产者线程
{
pthread_create(&threadArray[i], NULL, producter, (void*)&i);
}

for (i = 0; i < CUSTOMER_COUNT; i++)//创建消费者线程
{
pthread_create(&threadArray[i + CUSTOMER_COUNT], NULL, customer, (void*)&i);
}

for (i = 0; i < PRODUCTER_COUNT + CUSTOMER_COUNT; i++)//等待线程结束
{
pthread_join(threadArray[i], NULL);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: