pthread_cond_wait 和 pthread_cond_signal 的性能

Posted

技术标签:

【中文标题】pthread_cond_wait 和 pthread_cond_signal 的性能【英文标题】:pthread_cond_wait and pthread_cond_signal's performance 【发布时间】:2012-11-22 16:40:51 【问题描述】:

我有两个线程。 从队列中读取的一个。我不希望它在 while(1) 上运行来读取,所以我正在考虑在每次循环时给它一个条件变量:

while(1)
    while queue is not empty
        wait(cond)
        pop() 

代替:

while(1)
  while queue is not empty
      pop

和一个推送到队列的线程。如果我使用等待和信号方法,那么该线程需要通过每次推送弹出线程来通知(!) 问题是什么更好用? 如果队列大部分不是空的,那么发送信号是没有价值的(或者不是?)因为弹出线程没有等待,我担心它会降低性能。 但是,如果队列有一半时间是空的,那么在第二个 pop 方法中循环它可能是一个忙碌的等待。

我希望这里有人会通过取消向没有等待它的线程发送信号仍然可以的事实来消除我的恐惧

谢谢

【问题讨论】:

这些操作的性能是否有任何影响取决于您的程序正在执行的其他操作,因此衡量性能的唯一明智做法是衡量性能。 另外,使用条件变量使 push 和 pop 原子化的必要性通常是设计要求,而不是您可以决定不做的事情。 【参考方案1】:

首先要确保pthread_cond_signal 不会在signal(2) 意义上发送signal。它只是标记条件变量并释放任何等待它的变量。因此,如果您在消费进程正常调用之前调用pthread_cond_signal,那将被忽略。

其次,pthread_cond_wait 是快还是慢?这要看情况。你可以用得不好,也可以用得很好。如果你用得不好,我相信它会表现得很糟糕。如果你只在真正需要的时候等待,我认为它会表现得很好。

所以,既然你需要持有一个互斥体来使用条件变量,那么你不妨检查一下此时是否有数据(并将这个互斥体用作同步点)。

队列数据结构的一个想法:

struct q 
    struct qe *h;
    struct qe *t;

    pthread_mutex_t m;
    pthread_cond_t c;
    int len;
;

消费者(假设你只有一个消费者,如果有多个需要锁头检查):

void *consumer(void*arg) 
    struct q *q = arg;

    while(1) 
        pthread_mutex_lock(&q->m);
        if(q->h == NULL) 
            pthread_cond_wait(&q->c, &q->m);
        /* We hold the mutex when we exit pthread_cond_wait */
        pthread_mutex_unlock(&q->m); /* we can make the check without the mutex */
        while(q->h != NULL) 
            pthread_mutex_lock(&q->m);  /* but we need it to modify */
            pop(); 
            pthread_mutex_unlock(&q->m);
            /* Process data */
        
    

制作人:

void *producer(void*arg) 
    int i;
    struct q *q = arg;
    while(1) 
        pthread_mutex_lock(&q->m);
        push(q, some_data);
        if(q->h == q->t) /* only one element */
            pthread_cond_signal(&q->c);
        pthread_mutex_unlock(&q->m);
        
    return NULL;

【讨论】:

以上是关于pthread_cond_wait 和 pthread_cond_signal 的性能的主要内容,如果未能解决你的问题,请参考以下文章

pthread_cond_wait的等待和激发

pthread_cond_wait 和 pthread_cond_signal 的性能

pthread_cond_wait() 同时唤醒两个线程

pthread_cond_wait 丢失来自 pthread_cond_signal 的信号

Linux C语言 pthread_cond_wait()pthread_cond_timedwait()函数(不允许cond被唤醒时产生竞争,所以需要和互斥锁搭配)

多核处理器上的 pthread_cond_wait 问题