转自: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. 关于GreenOdoo的一个Bug

    动态创建字段的时候,虽然字段已经创建,但是显示的时候会报没有新创建的字段错误: 但是原版是没有任何问题的,记录一下.

  2. getElementsByClassName的兼容性

    /*----------------------------index.html------------------------------------*/ <!DOCTYPE html> ...

  3. Java 路径

    http://swiftlet.net/archives/713 Java中不存在标准的相对路径,各种相对路径取资源的方式都是基于某种规则转化为绝对路径.所以在Java中文件路径问题无非归结为一点:找 ...

  4. c#面向对象基础 封装、继承

    一.封装 这是一种隐藏的特性.可以用一个公式来展示类的封装特性: 封装的类=数据  +  对此数据进行的操作(即算法) 通俗的说,封装就是:包起外界不必要知道的东西,只向外界展露可供展示的东西. 在面 ...

  5. redis 安装(centos 6.4)

    我使用6.4系统,mark一下,其他版本应该也一样. wget wget http://download.redis.io/releases/redis-3.0.6.tar.gz make make ...

  6. chineseChess

    最近学习了chineseChess的Qt实现,把一些东西总结一下: 实现功能: 1.人人对战 2.人机对战 3.网络版 一.基础性工作:(人人对战) 1.棋盘和棋子的绘制(QPinter,drawLi ...

  7. 抽象工厂模式(Abstract Factory)

    GOF:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 类图:

  8. php课程---数组建立表单

    <?php $nation = array( array('n001','汉族'), array('n002','汉族'), array('n003','满族'), array('n004',' ...

  9. 使用JAXP对XML文档进行DOM解析

    import java.io.FileOutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers. ...

  10. Apache Spark技术实战之6 -- spark-submit常见问题及其解决

    除本人同意外,严禁一切转载,徽沪一郎. 概要 编写了独立运行的Spark Application之后,需要将其提交到Spark Cluster中运行,一般会采用spark-submit来进行应用的提交 ...