简体   繁体   English

pthread_cond_wait唤醒许多线程的示例

[英]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: 注意:

  1. The mutex must be locked. 互斥锁必须锁定。
  2. The predicate (thing you are waiting for) must be checked before waiting. 谓词(您正在等待的内容)必须在等待之前检查。
  3. The wait must be in a loop. 等待必须处于循环中。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM