Linux多线程之同步2 —— 生产者消费者模型,linux多线程


思路

生产者和消费者(互斥与同步)。资源用队列模拟(要上锁,一个时间只能有一个线程操作队列)。

m个生产者。拿到锁,且产品不满,才能生产。当产品满,则等待,等待消费者唤醒。当产品由空到不空,通知消费者。
n个消费者。拿到锁,且有产品,才能消费。当产品空,则等待,等待生产者唤醒。当产品由满到不满,通知生产者。
   
生产者条件:队列不满
消费者条件:队列不空
因此有两个条件变量。

代码

/*************************************************************************
  > File Name: main.c
  > Author: KrisChou
  > Mail:zhoujx0219@163.com
  > Created Time: Tue 26 Aug 2014 02:55:01 PM CST
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define CNT 20           /* 最多生产20个产品 */

/* 用队列模拟车间 */
/* front和tail初始化均为0,tail是下一个资源生成的下一个数组空间下标 */
typedef struct tag
{
    int s_arr[CNT + 1] ;   /* 生产20个产品,必须有21个空间,因为如果空间都装满产品,无法区别队列满和队列空 */
    int s_front ;
    int s_tail ;
}QUEUE,*pQUEUE ;
QUEUE my_que ;
/* 资源为空 */
int que_empty(pQUEUE pq)
{
    return pq ->s_front == pq -> s_tail ;
}
/* 资源为满 */
int que_full(pQUEUE pq)
{
    return  (pq -> s_tail + 1)% (CNT+1) == pq -> s_front ;
}
int que_cnt(pQUEUE pq)
{
    return (pq -> s_tail  - pq ->s_front + CNT + 1)% (CNT + 1) ;
}
pthread_mutex_t  mutex ;
pthread_cond_t cond_pro, cond_con ;

void* pro_handler(void* arg)
{
    pthread_detach(pthread_self());
    while(1)
    {
        pthread_mutex_lock(&mutex) ;
        while(que_full(&my_que))
        {
            pthread_cond_wait(&cond_pro, &mutex);
        }
        my_que.s_arr[my_que.s_tail ] = rand() % 1000 ;
        my_que.s_tail  = (my_que.s_tail + 1)% (CNT + 1) ;
        if(que_cnt(&my_que) == 1)
        {
            pthread_cond_broadcast(&cond_con);
        }
        printf("produce a product, total num : %d \n", que_cnt(&my_que));
        pthread_mutex_unlock(&mutex);
        sleep(rand()%3 + 1);
    }
}
void* con_handler(void* arg)
{
    pthread_detach(pthread_self());
    while(1)
    {
        pthread_mutex_lock(&mutex);
        while(que_empty(&my_que))
        {
            pthread_cond_wait(&cond_con, &mutex);
        }
        my_que.s_front = (my_que.s_front + 1) % (CNT + 1) ;
        if(que_cnt(&my_que) == CNT - 1)
        {
            /*由于我们的主线程是等消费者线程创建完之后,再创建生产者线程,
              因此一开始所有消费者线程都会挂起,在条件变量cond_pro的队列里排队
              因此需要用broadcast通知所有消费者线程。
              不然一次就通知一个生产者线程,就此消费者线程会抢锁。
              当然,如果一开始主线程先创建生产者线程,再创建消费者线程,
              由于生产者线程不会全部阻塞,因此可以使用signal来唤醒一个        */
            pthread_cond_broadcast(&cond_pro);
        }
        printf("consume a product, total num: %d \n", que_cnt(&my_que));
        pthread_mutex_unlock(&mutex);
        sleep(rand()%3 + 1);
    }

}
int main(int argc, char* argv[])//exe pro_num  con_num
{
    int con_cnt , pro_cnt ;
    my_que.s_front = 0 ; 
    my_que.s_tail = 0 ;
    pro_cnt = atoi(argv[1]) ;
    con_cnt = atoi(argv[2]) ;
    srand(getpid());
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond_pro, NULL);
    pthread_cond_init(&cond_con, NULL);
    pthread_t* arr = (pthread_t*)calloc(con_cnt + pro_cnt, sizeof(pthread_t));
    int index = 0 ;
    while(con_cnt > 0)
    {
        pthread_create(arr + index , NULL, con_handler, NULL);
        index ++ ;
        con_cnt -- ;
    }
    sleep(5);
    while(pro_cnt > 0)
    {
        pthread_create(arr + index , NULL, pro_handler, NULL);
        index ++ ;
        pro_cnt -- ;
    }
    while(1) ;
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond_pro);
    pthread_cond_destroy(&cond_con);
    return 0 ;
}
 Makefile
main:main.c
    gcc -o $@ $< -lpthread

linux下用多线程同步方法解决生产者-消费者问题

...........
你去搜下吧,这种是OS的经典题目,网上多的是源码。。。。
 

以生产者消费者模型为依据,提供一个多线程生产者-消费者实例,用VC或java实现,并具备以下

制片人:时存在的产品的时候,
消费者生产的产品是不够的:消费类产品
关键:当产品到达上限,停止生产,通知消费者的消费
关键2:当达到下限,停止消费,并通知生产者生产
共享数据:

代码
进口的java.util.ArrayList;
BR />公共类ProducerAndConsumer {
ArrayList的产品=新的ArrayList ();
MAX = 10;
布尔取消;

同步失效产生(){
int的大小= products.size();
(大小<MAX){
products.add(大小+“”);
} {
notifyAll()的;
}
}

同步的无效消耗(){
(products.isEmpty()){
尝试{
的wait();
}(InterruptedException的E){
e.printStackTrace();
}
}
System.out.println( “消费products.remove:”+(0));
}

私有类生产扩展Thread {
@覆盖
公共无效的run(){...... />(取消){
农产品();
}
}
}

私人阶层的消费扩展Thread {
@覆盖
公共无效的run(){
(取消){
消耗();
}
}
}
/>无效取消(){
取消= TRUE;
}

的公共ProducerAndConsumer(){
新的消费者()。开始();
新的的监制()。开始();}

公共静态无效的主要(字符串[] ARGS){
新ProducerAndConsumer();
}

}
 

相关内容

    暂无相关文章