• pthread_cond_broadcast & pthread_cond_signal


    pthread_cond_broadcast(&cond1)的作用是唤醒所有正在pthread_cond_wait(&cond1,&mutex1)的线程。

    pthread_cond_signal(&cond1)的的作用是唤醒所有正在pthread_cond_wait(&cond1,&mutex1)的至少一个线程。(虽然我还没碰到过多于一个线程的情况,但是man帮组手册上说的是至少一个)

    下面分为情况讨论一下这两个函数的效果。

    第一种情况:多个线程等待同一个cond,并且想对同一个mutex加锁。

     1 #include <stdio.h>
     2 #include <unistd.h>
     3 #include <pthread.h>
     4 #include <stdlib.h>
     5 
     6 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
     7 pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
     8 pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
     9 
    10 void* thread_task1(void* arg)
    11 {
    12     pthread_mutex_lock(&mutex1);
    13 
    14     pthread_cond_wait(&cond,&mutex1);
    15 
    16     printf("thread_task1 start working
    ");
    17     sleep(2);
    18     printf("thread_task1 works over
    ");
    19     pthread_mutex_unlock(&mutex1);
    20 
    21     return NULL;
    22 
    23 
    24 
    25 }
    26 
    27 void* thread_task2(void* arg)
    28 {
    29     pthread_mutex_lock(&mutex1);
    30 
    31     pthread_cond_wait(&cond,&mutex1);
    32 
    33     printf("thread_task2 start working
    ");
    34     sleep(2);
    35     printf("thread_task2 works over
    ");
    36     pthread_mutex_unlock(&mutex1);
    37 
    38     return NULL;
    39 
    40 
    41 }
    42 
    43 void* broadcastDiffMutex(void* arg)
    44 {
    45     pthread_cond_broadcast(&cond);
    46     return NULL;
    47 
    48 }
    49 
    50 void* signalDiffMutex(void* arg)
    51 {
    52     pthread_cond_signal(&cond);
    53     return NULL;
    54 
    55 }
    56 
    57 int main()
    58 {
    59     pthread_t thread_1,thread_2,thread_3;
    60     pthread_create(&thread_1,NULL,thread_task1,NULL);
    61     pthread_create(&thread_2,NULL,thread_task2,NULL);
    62     sleep(2);
    63 
    64 #ifdef SIGNAL
    65     pthread_create(&thread_3,NULL,signalDiffMutex,NULL);
    66 #else
    67     pthread_create(&thread_3,NULL,broadcastDiffMutex,NULL);
    68 #endif
    69 
    70 
    71     pthread_join(thread_1,NULL);
    72     pthread_join(thread_2,NULL);
    73     pthread_join(thread_3,NULL);
    74 
    75     return 0;
    76 
    77 }

    使用broadcast的运行结果:

     使用signal的运行结果:

    分析:

    1. 当使用broadcast方式时,两个被阻塞的线程都被唤醒了,被唤醒的线程将变为pthread_mutex_lock(mutex1)的状态,他们将抢着对mutex1加锁,在本次运行过程中thread_1加锁成功了,thread_2没有成功抢到锁,于是它就被阻塞了,在thread_1执行完毕释放锁后,会通知所有被阻塞在mutex1上的线程,于是thread_2最终成功拿到了锁,然后顺利执行。
    2. 当使用signal方式时,thread_1和thread_2中只被唤醒了一个线程,在本次运行中是thread_1被唤醒了,而因为thread_2没有被唤醒,他就一直卡在pthread_cond_wait处呼呼大睡,所以最终只有thread_1执行完毕。

     第二种情况:多个线程等待同一个cond,并且分别不同的mutex加锁。

     1 #include <stdio.h>
     2 #include <unistd.h>
     3 #include <pthread.h>
     4 #include <stdlib.h>
     5 
     6 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
     7 pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
     8 pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
     9 
    10 void* thread_task1(void* arg)
    11 {
    12     pthread_mutex_lock(&mutex1);
    13 
    14     pthread_cond_wait(&cond,&mutex1);
    15 
    16     printf("thread_task1 start working
    ");
    17     sleep(2);
    18     printf("thread_task1 works over
    ");
    19     pthread_mutex_unlock(&mutex1);
    20 
    21     return NULL;
    22 
    23 
    24 
    25 }
    26 
    27 void* thread_task2(void* arg)
    28 {
    29     pthread_mutex_lock(&mutex2);
    30 
    31     pthread_cond_wait(&cond,&mutex2);
    32 
    33     printf("thread_task2 start working
    ");
    34     sleep(2);
    35     printf("thread_task2 works over
    ");
    36     pthread_mutex_unlock(&mutex2);
    37 
    38     return NULL;
    39 
    40 
    41 }
    42 
    43 void* broadcastDiffMutex(void* arg)
    44 {
    45     pthread_cond_broadcast(&cond);
    46     return NULL;
    47 
    48 }
    49 
    50 void* signalDiffMutex(void* arg)
    51 {
    52     pthread_cond_signal(&cond);
    53     return NULL;
    54 
    55 }
    56 
    57 int main()
    58 {
    59     pthread_t thread_1,thread_2,thread_3;
    60     pthread_create(&thread_1,NULL,thread_task1,NULL);
    61     pthread_create(&thread_2,NULL,thread_task2,NULL);
    62     sleep(2);
    63 
    64 #ifdef SIGNAL
    65     pthread_create(&thread_3,NULL,signalDiffMutex,NULL);
    66 #else
    67     pthread_create(&thread_3,NULL,broadcastDiffMutex,NULL);
    68 #endif
    69 
    70 
    71     pthread_join(thread_1,NULL);
    72     pthread_join(thread_2,NULL);
    73     pthread_join(thread_3,NULL);
    74 
    75     return 0;
    76 
    77 }

    使用broadcast的效果:

    使用signal的效果

     分析:

    1. 当使用broadcast方式时,因为两个线程都被唤醒了,且它们想要加的锁并没有竞争关系,因此它们是并发执行的,而不必像前一种情况中那样必须一前一后执行。
    2. 当使用signal方式时,只被唤醒了一个线程,因此只有一个线程成功执行。

      

  • 相关阅读:
    004_列表list操作
    003_字符串str的操作
    002_python基础语录
    求哈夫曼树的编码
    Python笔记(一)——打印输出
    python基础一 day33 验证客户端的合法性
    python基础一 day32 复习
    python基础一 day30 网络编程
    python基础一 day29 logging
    python基础一 day29 学习方法(课前谈心)
  • 原文地址:https://www.cnblogs.com/XiaoXiaoShuai-/p/11855408.html
Copyright © 2020-2023  润新知