转自: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. Hibernate调用存储过程和函数

    操作大批量数据或复杂逻辑,考虑到执行效率和代码量的时候,存储过程和函数在数据库中是预编译好的,调用执行效率高 // 调用过程 {call 过程名称(?,?,?)} public static void ...

  2. 关于在VS 上发布网站

    在vs 上建立的网站只能用 localhost 进行访问,想要自己本机上的网站发布到IIS上面,这样就可以直接用 IP 地址来访问了,那么照如下的方式做: 1. 首先需要使用vs 发布自己的网站 1. ...

  3. C#控制台打印简单【倒三角形】的图形

    今天想练习一下简单的打印图形,小弟没有学过什么算法,嘿嘿,以后有更好的想法继续修改... static void InvertedTrainangle() { Console.WriteLine(&q ...

  4. linux中添加ftp用户,并设置相应的权限

    在linux中添加ftp用户,并设置相应的权限,操作步骤如下: 1.环境:ftp为vsftp.被限制用户名为test.被限制路径为/home/test 2.建用户:在root用户下: useradd ...

  5. const 指针的三种使用方式

    ///////////////////////const 指针的三种状态///////////////////// 注意:const 的前后顺序 const 在类型之前 ---可以修改指针包含的地址, ...

  6. The Earth Mover's Distance

    The EMD is based on the minimal cost that must be paid to transform one distribution into the other. ...

  7. 【7集iCore3基础视频】7-5 iTool2驱动安装

    iTool2驱动安装: 高清源视频:链接:http://pan.baidu.com/s/1dF5FtlB%20密码:g5x7 iCore3 购买链接:https://item.taobao.com/i ...

  8. cacti监控apache和nginx的配置

    一.监控apache1.下载http://forums.cacti.net/about25227.html&highlight=apachestats2.其中的ss_apache_stats. ...

  9. jqxGrid 绑定格式化

    var cellsrenderer = function(row, columnfield, value, defaulthtml, columnproperties) { ) || (row == ...

  10. 为什么要 MySQL 迁移到 Maria DB

    在Oracle收购了SUN公司之后, MySQL很不幸的落在了Oracle的手中,MySQL与Oracle DB存在竞争关系,很可能导致Oracle公司影响MySQL的开发与开放.MySQL之父Wid ...