linux笔记之条件变量

一.概念:

  • 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
  • 通俗来讲,互斥只是实现了安全问题,而有的时候,它并不高效,所以在此引出了条件变量,它可以用来实现高效。
  • 互斥锁和条件变量分别用来实现互斥和同步,是一对黄金搭档。

二.涉及的函数

  • 创建一个条件变量有两种方式

    • 定义一个全局变量如下:

      pthread_cond_t  cond=PTHREAD_COND_INITIALIZER;
    • 使用初始化函数:
      这里写图片描述

  • 条件变量的销毁函数
    这里写图片描述

  • 条件变量等待函数
    这里写图片描述
    条件变量有两个等待函数。二者的区别就在于pthread_cond_timedwait()比pthread_cond_wait()函数多了一个参数abstime,此参数可以设定等待超时,如果达到abstime所指定的时刻,仍然没有别的线程来唤醒当前线程,就返回ETIMEDOUT。
    pthread_cond_wait在阻塞式等待,这个函数做了以下三步操作:
    1.释放Muxtex
    2.阻塞等待
    3.当被唤醒时,重新获得Mutex并返回
  • 条件变量唤醒函数
    这里写图片描述
    有两个唤醒函数,区别是:
    pthread_cond_signal唤醒的是某个Condition Variable上等待的另一个线程,也可以调用
    pthread_cond_broadcast唤醒在这个Condition Variadle上等待的所有线程
    ##三.代码演示:
    下列程序演示了一个生产者-消费者的例子,表现同步互斥的效果
  • 以下代码是只加了互斥锁的代码,在消费者线程中加入了sleep(100);以达到增强生产者线程的竞争力的效果;代码以及效果图如下:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<pthread.h>
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
typedef struct _node
{
    struct _node*  _next;
    int data;
}_node,*_node_p,**_node_pp;

_node_p alloc(int data)
{
    _node_p _node=(_node_p)malloc(sizeof(data));
    if(_node==NULL)
    {
        perror("malloc");
        exit (0);
    }
    _node->data=data;
    _node->_next=NULL;
    return _node;
}
void delete_node(_node_p temp)
{
    if(!temp)
    free(temp);
}
static int is_empty(_node_p _h)
{
    if(NULL==_h->_next)
    {
        return 1;
    }
    return 0;
}
void show_List(_node_p _h)
{
    assert(_h);
    _node_p temp=_h->_next;
    while(NULL!=temp)
    {
        printf("%d ",temp->data);
        temp=temp->_next;
    }
    printf("\n");
}


void pop_List(_node_p _h,int* _o)
{
    if(!is_empty(_h))
    {
        _node_p temp=_h->_next;
        _h->_next=temp->_next;
        *_o=temp->data;
        delete_node(temp);
    }
}

void init_List(_node_pp _h)
{
    *_h=alloc(0);
}
void destory_List(_node_p _h)
{
    int data;
    while(is_empty(_h));
    {
        pop_List(_h,&data);
    }
    delete_node(_h);
}
void push_List(_node_p _h,int data)
{
    _node_p Newnode=alloc(data);
    Newnode->_next=_h->_next;   
    _h->_next=Newnode;
}
static void* consumer(void* _h)
{
    _node_p head=(_node_p) _h;
    for(;;)
    {
        pthread_mutex_lock(&lock);
        int data=rand()%1000;
        pop_List(head,&data);
        pthread_mutex_unlock(&lock);
        printf("consumer:%d\n",data);
        sleep(100);
    }
}
static void* producter(void* _h)
{
    _node_p head=(_node_p) _h; 
    for(;;)
    {
        pthread_mutex_lock(&lock);
        int i=rand()%1000;
        push_List(head,i);
        pthread_mutex_unlock(&lock);
        printf("producter:%d\n",i);
        sleep(1);
    }
}
int main()
{
    _node_p head=NULL;
    init_List(&head);
    pthread_t tid1;
    pthread_t tid2;
    pthread_create(&tid1,NULL,*consumer,head);
    pthread_create(&tid2,NULL,*producter,head);
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_cond_destroy(&cond);
    return 0;
}

结果图如下:
这里写图片描述
出现了只生产不消费的情况。
要解决如上问题:则需要时生产者和消费者同步起来:使用条件变量.

  • 使用条件变量解决上述问题:
    代码如下:
static void* consumer(void* _h)
{
    _node_p head=(_node_p) _h;
    for(;;)
    {
        pthread_mutex_lock(&lock);
        int data=rand()%1000;
        while(is_empty(head))
        {
            pthread_cond_wait(&cond,&lock);
        }
        pop_List(head,&data);
        pthread_mutex_unlock(&lock);
        printf("consumer:%d\n",data);
        sleep(100);
    }
}
static void* producter(void* _h)
{
    _node_p head=(_node_p) _h; 
    for(;;)
    {
        pthread_mutex_lock(&lock);
        int i=rand()%1000;
        push_List(head,i);
        pthread_mutex_unlock(&lock);
        printf("producter:%d\n",i);
        pthread_cond_signal(&cond);
        sleep(1);
    }
}

结果图:这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章