精华内容
下载资源
问答
  • 多线程(18) pthread_cond_broadcast1. pthread_cond_broadcast 唤醒所有被阻塞的线程1.1 pthread_cond_broadcastpthread_cond_signal2. 代码例子说明2.1 情况1:多个线程等待同一个cond,并且想对同一个mutex...

    1. pthread_cond_broadcast 唤醒所有被阻塞的线程

    1.1 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帮组手册上说的是至少一个)

    2. 代码例子说明

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

    2.1.1 使用 pthread_cond_signal 通知

    代码:

    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <stdlib.h>
    
    #define SIGNAL 1
    
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
    
    void* thread_task1(void* arg)
    {
    	pthread_mutex_lock(&mutex1);
    	pthread_cond_wait(&cond,&mutex1);
    	printf("thread_task1 start working\n");
    	sleep(2);
    	printf("thread_task1 works over\n");
    	pthread_mutex_unlock(&mutex1);
    	return NULL;
    }
    
    void* thread_task2(void* arg)
    {
    	pthread_mutex_lock(&mutex1);
    	pthread_cond_wait(&cond,&mutex1);
    	printf("thread_task2 start working\n");
    	sleep(2);
    	printf("thread_task2 works over\n");
    	pthread_mutex_unlock(&mutex1);
    	return NULL;
    }
    
    void* broadcastNotifyMutex(void* arg)
    {
    	pthread_cond_broadcast(&cond);
    	return NULL;
    }
    
    void* signalNotifyMutex(void* arg)
    {
    	pthread_cond_signal(&cond);
    	return NULL;
    }
    
    int main()
    {
    	pthread_t thread_1,thread_2,thread_3;
    	pthread_create(&thread_1,NULL,thread_task1,NULL);
    	pthread_create(&thread_2,NULL,thread_task2,NULL);
    	sleep(2);
    
    #ifdef SIGNAL
    	pthread_create(&thread_3,NULL,signalNotifyMutex,NULL);
    #else
    	pthread_create(&thread_3,NULL,broadcastNotifyMutex,NULL);
    #endif
    
    	pthread_join(thread_1,NULL);
    	pthread_join(thread_2,NULL);
    	pthread_join(thread_3,NULL);
    
    	return 0;
    }
    

    结果:

    [root@localhost test]# gcc b1.c -pthread
    [root@localhost test]# ./a.out 
    thread_task1 start working
    thread_task1 works over
    ^C
    [root@localhost test]#
    

    2.1.2 使用 pthread_cond_broadcast 通知

    代码:

    将上面的代码 SIGNAL 注释掉即可
    //#define SIGNAL 1
    

    结果:

    [root@localhost test]# ./a.out 
    thread_task1 start working
    thread_task1 works over
    thread_task2 start working
    thread_task2 works over
    [root@localhost test]# 
    

    2.1.3 分析:

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

    当使用signal方式时,thread_1和thread_2中只被唤醒了一个线程,在本次运行中是thread_1被唤醒了,而因为thread_2没有被唤醒,他就一直卡在pthread_cond_wait处呼呼大睡,所以最终只有thread_1执行完毕。

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

    2.2.1 使用 pthread_cond_signal 通知

    代码:

    将2.1.1代码添加并且thread_task2 中的 mutex1 修改为 mutex2。
    pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
    

    结果:

    [root@localhost test]# ./a.out 
    thread_task2 start working
    thread_task2 works over
    ^C
    [root@localhost test]# 
    

    2.2.2 使用 pthread_cond_broadcast 通知

    代码:

    将2.1.1代码添加并且thread_task2 中的 mutex1 修改为 mutex2。
    pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
    
    并且将 SIGNAL 注释掉即可
    //#define SIGNAL 1 
    

    结果:

    [root@localhost test]# gcc b4.c -pthread
    [root@localhost test]# ./a.out 
    thread_task1 start working
    thread_task1 works over
    thread_task2 start working
    thread_task2 works over
    [root@localhost test]# 
    

    2.2.3 分析:

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

    3.问题: 未解决,加printf 就不能通知

    就是在 分别在 thread_task1 thread_task2 函数开头加下面打印,pthread_cond_broadcast 方式只有一个线程打印
    printf(“111\n”);
    printf(“222\n”);

    参考

    说明:参考代码中情况1的mutex写错了。
    https://www.cnblogs.com/XiaoXiaoShuai-/p/11855408.html

    展开全文
  • pthread_cond_broadcast

    2012-08-31 16:37:07
    LINUX环境下多线程编程肯定会遇到需要条件变量的情况,此时必然要使用pthread_cond_wait()函数。但这个函数的执行过程比较难于理解。  pthread_cond_wait()的工作流程如下(以MAN中的EXAMPLE为例):  Consider ...

    LINUX环境下多线程编程肯定会遇到需要条件变量的情况,此时必然要使用pthread_cond_wait()函数。但这个函数的执行过程比较难于理解。
        pthread_cond_wait()的工作流程如下(以MAN中的EXAMPLE为例):
           Consider two shared variables x and y, protected by the mutex mut, and a condition vari-
           able cond that is to be signaled whenever x becomes greater than y.

                  int x,y;
                  pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
                  pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

           Waiting until x is greater than y is performed as follows:

                  pthread_mutex_lock(&mut);
                  while (x <= y) {
                          pthread_cond_wait(&cond, &mut);
                  }
                  /* operate on x and y */
                  pthread_mutex_unlock(&mut);

           Modifications on x and y that may cause x to become greater than y should signal the con-
           dition if needed:

                  pthread_mutex_lock(&mut);
                  /* modify x and y */
                  if (x > y) pthread_cond_broadcast(&cond);
                  pthread_mutex_unlock(&mut);

         这个例子的意思是,两个线程要修改X和 Y的值,第一个线程当X<=Y时就挂起,直到X>Y时才继续执行(由第二个线程可能会修改X,Y的值,当X>Y时唤醒第一个线程),即 首先初始化一个普通互斥量mut和一个条件变量cond。之后分别在两个线程中分别执行如下函数体:

                  pthread_mutex_lock(&mut);
                  while (x <= y) {
                          pthread_cond_wait(&cond, &mut);
                  }
                  /* operate on x and y */
                  pthread_mutex_unlock(&mut);

    和:       pthread_mutex_lock(&mut);
                  /* modify x and y */
                  if (x > y) pthread_cond_signal(&cond);
                  pthread_mutex_unlock(&mut);
     
        其实函数的执行过程非常简单,在第一个线程执行到pthread_cond_wait(&cond,&mut)时,此时如果X<=Y,则此函数就将mut互斥量解锁 ,再将cond条件变量加锁 ,此时第一个线程挂起 (不占用任何CPU周期)。
        而在第二个线程中,本来因为mut被第一个线程锁住而阻塞,此时因为mut已经释放,所以可以获得锁mut,并且进行修改X和Y的值,在修改之后,一个IF语句判定是不是X>Y,如果是,则此时pthread_cond_signal()函数会唤醒第一个线程 ,并在下一句中释放互斥量mut。然后第一个线程开始从pthread_cond_wait()执行,首先要再次锁mut , 如果锁成功,再进行条件的判断 (至于为什么用WHILE,即在被唤醒之后还要再判断,后面有原因分析),如果满足条件,则被唤醒 进行处理,最后释放互斥量mut 

        至于为什么在被唤醒之后还要再次进行条件判断(即为什么要使用while循环来判断条件),是因为可能有“惊群效应”。有人觉得此处既然是被唤醒的,肯定 是满足条件了,其实不然。如果是多个线程都在等待这个条件,而同时只能有一个线程进行处理,此时就必须要再次条件判断,以使只有一个线程进入临界区处理。 对此,转来一段:

    引用下POSIX的RATIONALE: 

    Condition Wait Semantics 

    It is important to note that when pthread_cond_wait() and pthread_cond_timedwait() return without error, the associated predicate may still be false. Similarly, when pthread_cond_timedwait() returns with the timeout error, the associated predicate may be true due to an unavoidable race between the expiration of the timeout and the predicate state change. 

    The application needs to recheck the predicate on any return because it cannot be sure there is another thread waiting on the thread to handle the signal, and if there is not then the signal is lost. The burden is on the application to check the predicate. 

    Some implementations, particularly on a multi-processor, may sometimes cause multiple threads to wake up when the condition variable is signaled simultaneously on different processors. 

    In general, whenever a condition wait returns, the thread has to re-evaluate the predicate associated with the condition wait to determine whether it can safely proceed, should wait again, or should declare a timeout. A return from the wait does not imply that the associated predicate is either true or false. 

    It is thus recommended that a condition wait be enclosed in the equivalent of a "while loop" that checks the predicate. 

    从上文可以看出: 
    1,pthread_cond_signal在多处理器上可能同时唤醒多个线程,当你只能让一个线程处理某个任务时,其它被唤醒的线程就需要继续 wait,while循环的意义就体现在这里了,而且规范要求pthread_cond_signal至少唤醒一个pthread_cond_wait上 的线程,其实有些实现为了简单在单处理器上也会唤醒多个线程. 
    2,某些应用,如线程池,pthread_cond_broadcast唤醒全部线程,但我们通常只需要一部分线程去做执行任务,所以其它的线程需要继续wait.所以强烈推荐此处使用while循环.

           其实说白了很简单,就是pthread_cond_signal()也可能唤醒多个线程,而如果你同时只允许一个线程访问的话,就必须要使用while来进行条件判断,以保证临界区内只有一个线程在处理。

    转贴:http://hi.baidu.com/yangyangye2008/blog/item/ee7bb186f8d3cd27c75cc37f.html

    展开全文
  • pthread_cond_broadcast——唤醒睡眠的线程,一次唤醒所有睡眠的线程 demon1——pthread_cond_signal #include <stdio.h> #include <pthread.h> static pthread_t thread1; static pthread_t thread2; ...

    pthread_cond_signal——唤醒睡眠的线程,一次只能唤醒一个线程
    pthread_cond_broadcast——唤醒睡眠的线程,一次唤醒所有睡眠的线程

    demon1——pthread_cond_signal

    #include <stdio.h>
    #include <pthread.h>
    
    static pthread_t thread1;
    static pthread_t thread2;
    
    //静态初始化
    static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
    static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
    
    void *function1()
    
    {
    	while(1)
    	{
    		pthread_mutex_lock(&lock);
    		printf("=====  线程1进入睡眠        ====\n");
    		pthread_cond_wait(&cond,&lock);
    		printf("====  线程1    唤醒    ====\n");
    		pthread_mutex_unlock(&lock);
    	}
    }
    
    void *function2()
    
    {
    	while(1)
    	{
    		pthread_mutex_lock(&lock);
    		printf("=====  线程2进入睡眠        ====\n");
    		pthread_cond_wait(&cond,&lock);
    		printf("====  线程2    唤醒    ====\n");
    		pthread_mutex_unlock(&lock);
    	}
    }
    
    
    int main()
    {
    	int i=0;
    	if(-1==pthread_create(&thread1,NULL,function1,NULL))
    	{
    		printf("thread_create1 fail!\n");
    		pthread_detach(thread1);
    	}
    
    	if(-1==pthread_create(&thread2,NULL,function2,NULL))
    	{
    		printf("thread_create fail!\n");
    		pthread_detach(thread1);
    	}
    
    	while(1)
    	{
    		sleep(2);
    		i++;
    		printf("\n 第%d次唤醒\n",i);
    		pthread_mutex_lock(&lock);
    		if(-1==pthread_cond_signal(&cond))
    		{
    			printf("pthread_cond_broadcast error!\n");
    		}
    		pthread_mutex_unlock(&lock);
    	}
    	return 0;
    }
    

    运行结果:
    在这里插入图片描述
    demon2——pthread_cond_broadcast

    #include <stdio.h>
    #include <pthread.h>
    
    static pthread_t thread1;
    static pthread_t thread2;
    
    //静态初始化
    static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
    static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
    
    void *function1()
    
    {
    	while(1)
    	{
    		pthread_mutex_lock(&lock);
    		printf("=====  线程1进入睡眠        ====\n");
    		pthread_cond_wait(&cond,&lock);
    		printf("====  线程1    唤醒    ====\n");
    		pthread_mutex_unlock(&lock);
    	}
    }
    
    void *function2()
    
    {
    	while(1)
    	{
    		pthread_mutex_lock(&lock);
    		printf("=====  线程2进入睡眠        ====\n");
    		pthread_cond_wait(&cond,&lock);
    		printf("====  线程2    唤醒    ====\n");
    		pthread_mutex_unlock(&lock);
    	}
    }
    
    
    int main()
    {
    	int i=0;
    	if(-1==pthread_create(&thread1,NULL,function1,NULL))
    	{
    		printf("thread_create1 fail!\n");
    		pthread_detach(thread1);
    	}
    
    	if(-1==pthread_create(&thread2,NULL,function2,NULL))
    	{
    		printf("thread_create fail!\n");
    		pthread_detach(thread1);
    	}
    
    	while(1)
    	{
    		sleep(2);
    		i++;
    		printf("\n 第%d次唤醒\n",i);
    		pthread_mutex_lock(&lock);
    		if(-1==pthread_cond_broadcast(&cond))
    		{
    			printf("pthread_cond_broadcast error!\n");
    		}
    		pthread_mutex_unlock(&lock);
    	}
    	return 0;
    }
    

    运行结果:
    在这里插入图片描述
    对比运行结果,清楚的可以发现pthread_cond_broadcast可以唤醒所有睡眠的线程

    展开全文
  • 使用pthread_cond_signal只能唤醒N个线程中的一个,而pthread_cond_broadcast可以唤醒全部的N个线程。 实例: #include<stdio.h> #include<unistd.h> #include<pthread.h> #define MAX_THREAD_...

    使用pthread_cond_signal只能唤醒N个线程中的一个,而pthread_cond_broadcast可以唤醒全部的N个线程。

    实例: 

    #include<stdio.h>
    #include<unistd.h>
    #include<pthread.h>
    #define MAX_THREAD_NUM 5
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    void* thread_fun(void* arg)
    {
        int index = *(int*)arg;
        printf("[%d]thread start up!\n", index);
        pthread_mutex_lock(&mutex);
        printf("[%d]thread wait...\n", index);
        pthread_cond_wait(&cond, &mutex);
        printf("[%d]thread wake up\n", index);
        pthread_mutex_unlock(&mutex);
        pthread_exit(0);
    }
    int main()
    {
        pthread_t tid[MAX_THREAD_NUM];
    
        for(int i = 0; i < MAX_THREAD_NUM; i++)
        {
            pthread_create(&tid[i], NULL, thread_fun, &i);
            sleep(1);
        }
        sleep(3);
        //pthread_cond_signal(&cond);	//唤醒N个线程中的一个
        pthread_cond_broadcast(&cond);	//全部唤醒
        for(int i = 0; i < MAX_THREAD_NUM; ++i)
        {
            pthread_join(tid[i], NULL);
        }
        return 0;
    }

    运行结果:

     

    展开全文
  • 1.下面情况适合用pthread_cond_broadcast 一个生产者多消费者,生产者能一次产生多个产品的情况。 多生产者多消费者 读写锁实现(写入之后,通知所有读者) 2.下面情况适合pthread_cond_signal的情况 ...
  • pthread_cond_broadcast使用示例

    万次阅读 2017-04-23 23:14:22
    今天在使用pthread_cond_t时,发现pthread_cond_t使用pthread_cond_broadcast函数唤醒多个条件变量时,使用两个互斥量分别控制时,只能唤醒其中一个变量,最后通过测试发现只能使用一个互斥量去控制。 个人理解: ...
  • pthread_cond_broadcast相关

    2017-05-10 19:09:55
    pthread_cond_broadcast相关
  • pthread_cond_wait() 用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait()函数一进入wait状态...
  • 1.适用pthread_cond_broadcast 1.一个生产者多消费者,生产者能一次产生多个产品的情况。 2.多生产者多消费者 3.读写锁实现(写入之后,通知所有读者) 2.适用pthread_cond_signal的情况 1.单一生产者,生产者...
  • liunx:pthread_cond_t条件变量pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast 一、pthread_cond_t条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程...
  • #include <...static pthread_cond_t cond; static pthread_mutex_t mutex1; static pthread_mutex_t mutex2; void *thread1_entry(void *arg) { while(1) { pthread_mutex_lock(&mutex1); .
  • pthread_cond_broadcast()

    千次阅读 2017-06-16 11:59:08
    pthread_cond_timedwait()函数阻塞住调用该函数的线程,等待由cond指定的条件被触发(pthread_cond_broadcast() or pthread_cond_signal())。 当pthread_cond_timedwait()被调用时,调用线程必须已经锁住了mutex...
  • 前言 pthread_mutex_lock是在多线程...生产者在写入消息的时候,调用pthread_cond_broadcast来唤醒消费者。本来以为这样很完美,在测试环境也没有测出什么问题。 然而上线后上游直接报ring buffer full,定位出下游.
  • LINUX环境下多线程编程肯定会遇到需要条件变量的情况,此时必然要使用pthread_cond_wait()函数。但这个函数的执行过程比较难于理解。  pthread_cond_wait()的工作流程如下(以MAN中的EXAMPLE为例):  Consider ...
  • 关于pthread_cond_signal与pthread_cond_broadcast的使用说明 分类: Java C/C++2006-08-23 10:59 11330人阅读 评论(3) 收藏 举报 signal多线程struct  在code review中,我会发现很多人喜欢在...
  • pthread_cond_timedwait()函数阻塞住调用该函数的线程,等待由cond指定的条件被触发(pthread_cond_broadcast() or pthread_cond_signal())。 当pthread_cond_timedwait()被调用时,调用线程必须已经锁住了mutex。...
  • The pthread_cond_broadcast() and pthread_cond_signal() functions shall have no effect if there are no threads currently blocked on cond.If no thread is blocked on the condition, the subroutine succe
  • #include #include #include #include pthread_mutex_t mymutex1 = PTHREAD_MUTEX_INITIALIZER;  pthread_mutex_t mymutex2 = PTHREAD_MUTEX_INITIALIZER;... pthread_cond_t mycond = PTHREAD_COND_INITI
  • 关于Posix通用线程的概述请参考POSIX 线程详解 ...pthread_cond_broadcastpthread_cond_wait的使用有这样的一篇: http://fengmenghello.blog.163.com/blog/static/1646203302010718101712356/ 笔者建议在Linu...
  • 条件变量 概念: 专门为了互斥锁而诞生的辅助工具,条件变量是一种同步机制,允许线程挂起,直到共享数据上的某些条件得到满足。条件变量上的基本操作有:触发条件(当条件变为 true 时);...int pthread_cond_i...
  • 条件锁(条件Mutex)pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast的使用[转]  (2012-05-26 17:04:45) 转载▼ 标签:  杂谈 分类: 驱动程序1 LINUX环境...
  • LINUX环境下多线程编程肯定会遇到需要条件变量的情况,此时必然要使用pthread_cond_wait()函数。但这个函数的执行过程比较难于理解。 pthread_cond_wait()的工作流程如下(以MAN中的EXAMPLE为例): Consider two ...
  • pthread线程使用小结 1.奇怪的线程参数初始化 for( i=0; i { //会有什么问题? pthread_create(&tid,NULL, &thread_client_function, (void*)&i ); } 上面代码应该很容易明白,创建多个线程,传入序列号...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,288
精华内容 3,715
关键字:

pthread_cond_broadcast