我目前正在使用条件variables来同步两个线程(pthreads),并得到一个意外的行为,尽pipe我已经validation了一个线程已经在等待一个条件,但是当另一个线程在这个条件上发出信号时,它不会被唤醒。
值得一提的是,我已经在桌面环境下运行了这个程序,并且运行正常,但是当我使用uclibc在embedded式环境中运行程序时,出现了这个问题。
为了排除故障,我将我的代码分解为两个执行locking/解锁/信号的线程,如下所示:
#include <stdio.h> #include <pthread.h> #include <stdbool.h> pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t condition1 = PTHREAD_COND_INITIALIZER; pthread_cond_t condition2 = PTHREAD_COND_INITIALIZER; bool predicate1 = false; bool predicate2 = false; static void * ThreadFunc2(void * arg) { sleep(1); // For testing purposes,ensures this thread is run after Thread1 pthread_mutex_lock(&mutex2); while(1) { pthread_mutex_lock(&mutex1); // Do some work - Eg receive some data from a socket predicate1 = false; pthread_cond_signal(&condition1); pthread_mutex_unlock(&mutex1); predicate2 = true; while(predicate2 == true) pthread_cond_wait(&condition2,&mutex2); // Do some more work - Eg send response data to socket } } static void * ThreadFunc1(void * arg) { int result; pthread_mutex_lock(&mutex1); while(1) { predicate1 = true; while(predicate1 == true) pthread_cond_wait(&condition1,&mutex1); // Do some work - Eg process data on the socket and prepare response data to be sent pthread_mutex_lock(&mutex2); predicate2 = false; pthread_cond_signal(&condition2); pthread_mutex_unlock(&mutex2); } } int main(int argc,char * argv[]) { pthread_t thread1Id,thread2Id; pthread_create(&thread1Id,NULL,ThreadFunc1,NULL); pthread_create(&thread2Id,ThreadFunc2,NULL); while(1) { sleep(1); } return 0; }
如果我排除所有与mutex2 / condition2 / predicate2有关的语句,则两个线程按照预期一起工作。
了解来自多个进程的并发文件写入
在Windows上安装PygraphViz,Python 2.6
如何用C#.NET编写程序,在Linux / Wine / Mono上运行它们?
当在C程序中使用termios.h询问用户的input时,如何使箭头键和退格键正确工作?
与Valgrind一起运行时,malloc返回null
使用上面列出的代码,在短时间之后(因为所有的工作都被剥离了,每个循环都运行得非常快),ThreadFunc1中的等待条件1不会被唤醒,即使它被Threadfunc2指示,导致应用程序被暂停。
另外为了帮助我debugging,我已经重新定义了pthread_ *函数,在调用实际的pthread_ *函数之前,用匹配的行号向stdout输出消息。 这使我能够跟踪每个pthread操作的stream程,并validation信号正在发送到已经等待的状态。
任何人都可以请帮我澄清一下我上面实现的潜在问题吗?
在此先感谢您的任何build议。
守护进程中的DST更改处理(* NIX)
C程序尝试修改文本段中的位置
如何一致地重播一个事件列表
你的错误是,在调用pthread_cond_wait()之后,你不能解锁条件变量所使用的互斥锁。
例如pthread_cond_wait()在线程被阻塞的时候在内部解锁互斥锁,但是当它被唤醒时它会重新获得锁,并且你需要明确地释放它。
有关cond的更多详细信息,请参阅本教程。 变量: https : //computing.llnl.gov/tutorials/pthreads/#ConditionVariables
我遇到过类似的问题。 在我的情况下,有时候信号是在阻塞的线程等待之前发送的。 在这种情况下的行为是两个线程“卡住”。 我们通过添加一个通知信号被发送的标志来解决它。
解决方案 – 请参阅以下说
在信号调用pthread_cond_signal()之前放置pthread_mutex_unlock(),而不是在它之后解决问题
... pthread_mutex_lock(&mutex1); predicate1 = false; pthread_mutex_unlock(&mutex1); pthread_cond_signal(&condition1); ...
在函数ThreadFunc2和类似的线程1
... pthread_mutex_lock(&mutex2); predicate2 = true; pthread_mutex_unlock(&mutex2); pthread_cond_signal(&condition2); ...
在函数ThreadFunc1中。
说明在程序中,线程2进入信号调用
pthread_cond_signal(&condition1); // thread 2 with mutex1 locked
与mutex1锁定。 线程1只能离开阻塞
pthread_cond_wait(&mutex1); // thread 1 leaves only after mutex1 unlocked
调用自己锁定mutex1这是这个函数调用的保证行为 – 这意味着它应该被所有其他线程解锁,以继续。 如果你有一个pthread_cond_signal()的实现阻塞,直到接收到信号的线程继续,那么在锁定对应的互斥锁进入调用时会产生一个死锁。 这也可以解释为什么一个环境可以很好地工作,而另一个环境则不会:例如,当您的桌面环境没有在嵌入式环境中阻塞对pthread_cond_signal()的调用时。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。