线程的生产者消费者模型

来源:互联网 发布:plc编程梯形图简单实例 编辑:程序博客网 时间:2024/05/18 01:48

1. 基于单链表的生产者与消费者模型

  1. 生产者—消费者模型的321原则:
    3种关系:

        生产者-生产者 ***互斥***    消费者-消费者 ***互斥***    生产者-消费者 ***互斥,同步***

    2种角色:

    消费者 生产者

    1个交易场所:

    临界资源
  2. 实现321的方法:

1个交易场所:创建一个带头节点的链表:

typedef struct _head //结构体声明{    int data;    struct _head *next;}Node,*Node_p,**Node_pp;Node_p head; //头指针声明void InitList(Node_pp _h) //初始化带头节点链表{    *_h =(Node_p)malloc(sizeof(Node));    (*_h)->next = NULL;}void PushFrond(Node_p _h,int K)//{    Node_p tmp = _h->next;    _h->next =(Node_p)malloc(sizeof(Node));    _h = _h->next;    _h->data = K;    _h->next = tmp;}Node_p PopFrond(Node_p _h){    if(_h->next == NULL)        return NULL;    Node_p tail = _h->next;    _h->next = tail->next;    return tail;}

两个角色:我们需要创建两个线程:

void *consume(void *arg) // 用于消费,即调用PopFrondvoid &product(void *arg) //用于生产,即调用PushFrond

互斥:函数consume与product不能运行临界区,即消费者,生产者不能同时访问临界资源(不能同时改变链表head):
我们可以用互斥锁

pthread_mutex_t mutex_lock = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_lock(&mutex_lock);//加锁pthread_mutex_unlock(&mutex_lock);//解锁

同步:消费者不能超过生产者消费,当消费者发现没有资源时,就挂起等待,当生产者放入资源后发送信号唤醒消费者消费;
可以用条件变量即同时满足同步:

pthread_cond_t  cond = PTHREAD_COND_INITIALIZER; pthread_cond_wait(&cond,&mutex_lock);//等待pthread_cond_signal(&cond);//发信号
信号的功能:1.释放锁 //让其他线程访问临界区2. 阻塞等待/3. 唤醒时重新获得锁

消费者-生产者模型编写:

void* product(void *arg){    while(1){        int n = rand()/12123;        pthread_mutex_lock(&mutex_lock);    //解锁访问        PushFrond(head,n);        printf("product done! %d\n",n);        pthread_mutex_unlock(&mutex_lock);//解锁        pthread_cond_signal(&cond);//生产完成,发送信号,消费者消费        sleep(2);    }    return NULL;}void *consum(void *arg){    while(1){        pthread_mutex_lock(&mutex_lock);//加锁访问        Node_p tmp = PopFrond(head);        while(tmp == NULL)//当没有资源时,则阻塞等待        {            pthread_cond_wait(&cond, &mutex_lock);            tmp = PopFrond(head);        }        printf("consum done! %d\n",tmp->data);        pthread_mutex_unlock(&mutex_lock);//解锁    }    return NULL;}