[英]pthread_cond_wait wake many threads example
pthread_cond_wait wake many threads example pthread_cond_wait唤醒许多线程的示例
Code to wake up thread 1 & 3 on some broadcast from thread 0. 在线程0的某些广播中唤醒线程1和3的代码。
Setup: Win7 with mingw32, g++ 4.8.1 with mingw32-pthreads-w32 pthread condition variable 设置:Win7 with mingw32,g ++ 4.8.1 with mingw32-pthreads-w32 pthread条件变量
Solution: http://pastebin.com/X8aQ5Fz8 解决方案: http : //pastebin.com/X8aQ5Fz8
#include <iostream>
#include <string>
#include <list>
#include <map>
#include <pthread.h>
#include <fstream>
#include <sstream> // for ostringstream
#define N_THREAD 7
using namespace std;
// Prototypes
int main();
int scheduler();
void *worker_thread(void *ptr);
string atomic_output(int my_int, int thread_id);
// Global variables
//pthread_t thread0, thread1, thread2, thread3, thread4, thread5, thread6, thread7;
pthread_t m_thread[N_THREAD];
int count = 1;
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
// Main
int main() {
cout << "Launching main. \n";
//Start to monitor for exceptions
register_exception_handler();
//Start scheduler
scheduler();
return 0;
}
// Scheduler
int scheduler() {
// Starting scheduler log file
ofstream scheduler_log;
scheduler_log.open ("scheduler_log.txt");
//scheduler_log << "[Scheduler] Starting." << endl;
cout << "[Scheduler] Starting. \n";
// Scheduler::Main Section
int thread_id[N_THREAD];
for(int i=0;i<N_THREAD;i++) {
thread_id[i] = i;
pthread_create( &m_thread[i], NULL, worker_thread, (void *) &thread_id[i]);
}
for(int i=0;i<N_THREAD;i++)
pthread_join(m_thread[i], NULL);
cout << "[Scheduler] Ending. \n";
// Closing scheduler log file
scheduler_log.close();
return 0;
}
string atomic_output(int my_int, int thread_id) {
ostringstream stm;
stm << "Thread ";
stm << thread_id;
stm << ": ";
//count fn
stm << my_int;
stm << "\n";
//stm << "Finished. \n";
return stm.str();
}
void *worker_thread(void *ptr) {
string line;
//int boo = 0;
int thread_id = *(int *) ptr;
//if(thread_id == 0)
// pthread_mutex_lock( &count_mutex );
for(int i=0;i<10;i++) {
//boo++;
if (thread_id == 1) {
pthread_mutex_lock(&count_mutex);
while (count == 1) {
cout << "[Thread 1] Before pthread_cond_wait...\n";
pthread_cond_wait( &condition_var, &count_mutex );
cout << "[Thread 1] After pthread_cond_wait...\n";
}
pthread_mutex_unlock(&count_mutex);
}
if (thread_id == 3) {
pthread_mutex_lock(&count_mutex);
while (count == 1) {
cout << "[Thread 3] Before pthread_cond_wait...\n";
pthread_cond_wait( &condition_var, &count_mutex );
cout << "[Thread 3] After pthread_cond_wait...\n";
}
pthread_mutex_unlock(&count_mutex);
}
//count fn
line = atomic_output(i, *(int *)ptr);
cout << line;
if (i == 5) {
if(thread_id == 0) {
pthread_mutex_lock( &count_mutex );
count = 0;
pthread_mutex_unlock( &count_mutex );
pthread_cond_broadcast(&condition_var);
}
}
}
//line = atomic_output(0, *(int *)ptr);
//cout << line;
}
(old) -= What I've tried =- (旧的)-=我尝试过的=-
*Edit: early problem in the code with while(0) instead of while(predicate). *编辑:使用while(0)而不是while(predicate)的代码中的早期问题。 Keeping it there for easy reference with the comments.
将其保留在此处以便于注释轻松参考。
Code 1: http://pastebin.com/rCbYjPKi 代码1: http : //pastebin.com/rCbYjPKi
I tried to while(0) pthread_cond_wait( &condition_var, &count_mutex ); 我试图while(0)pthread_cond_wait(&condition_var,&count_mutex); with pthread_cond_broadcast(&condition_var);
使用pthread_cond_broadcast(&condition_var); ... The thread does not respect the condition.
...线程不遵守条件。
Proof of condition non-respect : http://pastebin.com/GW1cg4fY 不遵守条件的证明: http : //pastebin.com/GW1cg4fY
Thread 0: 0
Thread 0: 1
Thread 0: 2
Thread 0: 3
Thread 2: 0
Thread 6: 0
Thread 1: 0 <-- Here, Thread 1 is not supposed to tick before Thread 0 hit 5. Thread 0 is at 3.
Code 2: http://pastebin.com/g3E0Mw9W 代码2: http : //pastebin.com/g3E0Mw9W
I tried pthread_cond_wait( &condition_var, &count_mutex ); 我尝试了pthread_cond_wait(&condition_var,&count_mutex); in thread 1 and 3 and the program does not return.
在线程1和3中,程序不会返回。
either thread 1, or thread 3 waits forever. 线程1或线程3永远等待。 Even using broadcast which says it should wake up all waiting threads.
即使使用广播说应该唤醒所有等待的线程。 Obviously something is not working, code or lib?
显然有些东西不起作用,代码还是lib?
More: 更多:
I've tried to unlock the mutex first, then broadcast. 我尝试先解锁互斥锁,然后广播。 I've tried to broadcast then unlock.
我尝试播放然后解锁。 Both don't work.
两者都不起作用。
I've tried to use signal instead of broadcast, same problem. 我试图用信号代替广播,同样的问题。
References that I can't make work (top google search) 我无法使用的参考资料(排名靠前的Google搜索)
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
http://docs.oracle.com/cd/E19455-01/806-5257/6je9h032r/index.html http://docs.oracle.com/cd/E19455-01/806-5257/6je9h032r/index.html
http://www-01.ibm.com/support/knowledgecenter/ssw_i5_54/apis/users_76.htm http://www-01.ibm.com/support/knowledgecenter/ssw_i5_54/apis/users_76.htm
Code 3: http://pastebin.com/tKP7F8a8 代码3: http : //pastebin.com/tKP7F8a8
Trying to use a predicate variable count, to fix race problem condition. 尝试使用谓词变量计数来解决竞争问题条件。 Still a problem, doesn't prevent thread1 and thread3 from running when thread0 is between 0 and 5.
仍然是一个问题,当线程0在0到5之间时,不会阻止线程1和线程3运行。
What would be the code to wake up thread 1 & 3 on some function call from thread0 从thread0进行某些函数调用时唤醒线程1和3的代码是什么?
if(thread_id == 0)
pthread_mutex_lock( &count_mutex );
for(int i=0;i<10;i++) {
//boo++;
if (thread_id == 1) {
while(0)
pthread_cond_wait( &condition_var, &count_mutex );
}
None of this makes any sense. 这些都没有任何意义。 The correct way to wait for a condition variable is:
等待条件变量的正确方法是:
pthread_mutex_lock(&mutex_associated_with_condition_variable);
while (!predicate)
pthread_cond_wait(&condition_variable, mutex_associated_with_condition_variable);
Notice: 注意:
Breaking any of these three rules will cause the kind of problems you are seeing. 违反这三个规则中的任何一个都会引起您所遇到的问题。 Your main problem is that you break the second rule, waiting even when the thing you want to wait for has already happened.
您的主要问题是您违反了第二条规则,即使您要等待的事情已经发生也要等待。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.