转自:http://stackoverflow.com/questions/16819169/why-does-pthread-cond-signal-not-work#

0 down vote favorite

 

I am currently learing all around POSIX threads (pthread).

I now have created a simple program which increased a shared value by 7 until above 10000 then it should signal a condition to the next thread which decreases it by 3 until under 1000. At last it should divide the result through 2 and main should output the result.

my code

pthread_t threads[];
pthread_cond_t cond_a, cond_b;
pthread_mutex_t mutex; int counter; void * worker_one();
void * worker_two();
void * worker_three(); int main(int argv, const char ** argc) {
counter = ; pthread_cond_init(&cond_a, NULL);
pthread_cond_init(&cond_b, NULL);
pthread_mutex_init(&mutex, NULL); pthread_create(&threads[], NULL, worker_one, NULL);
pthread_create(&threads[], NULL, worker_two, NULL);
pthread_create(&threads[], NULL, worker_three, NULL); pthread_join(threads[], NULL);
pthread_join(threads[], NULL);
pthread_join(threads[], NULL); printf("Value started at %d and ends with %d.\n", , counter); return ;
} void * worker_one() {
printf("Worker one started.\n"); pthread_mutex_lock(&mutex); printf("Worker one starting work.\n");
while (counter < ) {
counter += ;
} pthread_cond_signal(&cond_a); printf("Worker one finished work with: %d.\n", counter); pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
} void * worker_two() {
printf("Worker two started.\n"); pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond_a, &mutex); printf("Worker two starting work.\n");
while (counter > )
counter -= ; printf("Worker two finished work with: %d.\n", counter); pthread_cond_signal(&cond_b);
pthread_mutex_unlock(&mutex); sleep(); pthread_exit(NULL);
} void * worker_three() {
printf("Worker three started.\n"); pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond_b, &mutex); printf("Worker three starting work.\n"); counter /= ; printf("Worker three finished work with: %d.\n", counter); pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}

For some reason the whole execution hangs around the first thread. The signal is also fired but thread two does not react.

Can somebody tell me what I am doing wrong?

 
Could somebody tell me why down vote? – bodokaiser May 29 '13 at 16:23
    
I've moved the code from gist to SO. Don't just link to code on an external site, please include relevant code in the question. – user7116 May 29 '13 at 16:25
    
ok did not knew anything about this – bodokaiser May 29 '13 at 16:25

6 down vote accepted

 

I have answered a similar question here: pthread condition variables on Linux, odd behaviour.

The problem is that you wait before even testing the condition you want to wait for is true. What happens is that thread 1 signals before thread 2 is waiting, therefore the signal is lost and thread 2 will be waiting forever.

In order to avoid this, first test what you want to wait for, then wait only if it's not here.

EDIT: Ok, here is a possible solution with only one mutex and one condtion (untested)

Thread 1:

pthread_mutex_lock(&mutex);
while(thread_1_should_work == false){ // wait until the condition is satisfied
pthread_cond_wait(&cond, &mutex);
} //at this point, we owe the mutex and we know thread_1_should_work is true; // do work thread_1_shoudl_work = false;
thread_2_should_work = true; pthread_cond_broadcast(&cond); //wake up any waiting thread (if it's not their turn, they'll call wait again)
pthread_mutex_unlock(&mutex);
Is the testing case a simple external flag or something pthread internal? I use the example from computing.llnl.gov/tutorials/pthreads but there are no flags actually – bodokaiser May 29 '13 at 16:33
 
 
@bodokaiser: you'll have to make up a variable, but a simple boolean flag will do. Spurious wakeups are a reality unfortunately. – user7116 May 29 '13 at 16:35
 
@sixlettervariables so the main idea of conditions are just some more specific mutex signaling (with out the actual locking). Is this correct? – bodokaiser May 29 '13 at 16:36
 
Yes, in your case is thread_is_working flag would work (except that it has more than 6 letters :) I think the answer that the linked answer can help. – Ben May 29 '13 at 16:38
 
Actually, wait() releases the mutex and yield the thread atomically so that nothing happens while the thread is being yield. – Ben May 29 '13 at 16:41

Why does pthread_cond_signal not work?【转】的更多相关文章

  1. pthread_cond_signal惊群现象

    1.如下代码所示: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include < ...

  2. 关于 pthread_cond_wait 和 pthread_cond_signal , signal 无效的问题

    关于一个消费者模式,,,引起的问题.. 我在io线程里不断的把一个函数调用放到队列里 然后ruby线程就不断的从这个队列里取出函数之争并运行. 典型的 消费者模式. 我曾经以为是这样... 这是wor ...

  3. 深入理解pthread_cond_wait、pthread_cond_signal

    ===============================man pthread_cond_wait的解释========================== LINUX环境下多线程编程肯定会遇到 ...

  4. 条件变脸pthread_cond_signal丢失问题

    直接上代码: static bsem_t bsem; void* t1(void *arg) { /*printf("enter task 1\n");*/ /*while(1)* ...

  5. pthread_cond_wait和pthread_cond_signal以及互斥变量的使用情况

    #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h& ...

  6. pthread_cond_signal该放在什么地方?

    pthread_cond_signal()的具体位置? "pthread_cond_signal()必须要放在pthread_mutex_lock() 和pthread_mutex_unlo ...

  7. 线程相关函数(6)-pthread_cond_wait(),pthread_cond_signal(), 条件变量

    pthread_cond_tpthread_cond_initpthread_cond_destroypthread_cond_waitpthread_cond_timedwaitpthread_co ...

  8. 条件变量pthread_cond_wait()和pthread_cond_signal()详解

    条件变量        条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起:另一个线程使"条件成立" ...

  9. 【转】pthread_cond_signal 虚假唤醒问题

    引用:http://blog.csdn.net/leeds1993/article/details/52738845 什么是虚假唤醒? 举个例子,我们现在有一个生产者-消费者队列和三个线程. I.1号 ...

随机推荐

  1. CAS单点登录系统整合——注册的问题

    最近一段时间在搞CAS单点登录系统,涉及到几个子系统的整合问题.对于注册,这里遇到了一个选择: 在子系统内完成注册,然后把信息同步到CAS系统: 在CAS系统中完成基本信息的注册,比如:用户名.邮箱. ...

  2. nginx基于IP的虚拟主机

    知识点: server的语法: upstream语法: upstream中192.168.100.1不是ip只是个标识,只要和下面的proxy_pass 对应即可. 基于IP的虚拟主机: listen ...

  3. 让Session失效的三种方法

    我们设置SESSION失效的时间,是为了确保在用户长时间不与服务器交互的情况下,可以自动退出登录.本文介绍了三种设置SESSION失效的方法,希望对你有帮助. Session对象是HttpSessio ...

  4. XML真正强大的功能是来自其元素与封装的内容

    创建文档类型声明 一般而言,XML声明放在文档顶部.在PHP中声明十分简单:只需实例化一个DOM文档类的对象并赋予它一个版本号.查看程序清单A: 程序清单 A <?php// create do ...

  5. PHP如何通过SQL语句将数据写入MySQL数据库呢?

    1,php和MySQL建立连接关系 2,打开 3,接受页面数据,PHP录入到指定的表中 1.2两步可直接使用一个数据库链接文件即可:conn.php <?phpmysql_connect(&qu ...

  6. iPhone6手機產品提交了進網申請

    近期,海外投資蘋果公司為iPhone6手機產品提交了進網申請,經電信設備進網檢測機構測試和我部審查,相關產品滿足進網管理要求.根據<電信條例>有關規定,我部依法定程式在法定時限內為蘋果公司 ...

  7. 关于svn的使用

    svn听课笔记 1. 下载并安装svn2. 将svn安装目录中bin目录添加到用户path变量中.3. 创建svn根目录svnroot4. 启动svn服务 在dos启动命令: svnserve -d ...

  8. asp.net identity 2.2.0 中角色启用和基本使用(五)

    建立控制器UsersAdminController 第一步:在controllers文件夹上点右键>添加>控制器, 我这里选的是“MVC5 控制器-空”,名称设置为:UsersAdminC ...

  9. Android WebApp开发使用Genymotion连接Fiddler2/Charles代理调试

    1.       目的 在模拟器的浏览器或app hybrid开发中遇到chrome调试代码为线上代码或者混淆代码时,可以利用fiddler/charles为genymotion配置代理, 可以方便的 ...

  10. yii2知识点理解(成员属性)

    yii2成员属性 成员变量类似于public $a; 成员属性类似于 public function a(){} 成员变量是就类的结构构成而言的概念,而属性是就类的功能逻辑而言的概念 成员属性应用: ...