C++ pthread_cond_wake多线程示例

C++ pthread_cond_wake多线程示例,c++,pthreads,mingw,mutex,mingw32,C++,Pthreads,Mingw,Mutex,Mingw32,pthread_cond_wake多线程示例 从线程0的某些广播中唤醒线程1和3的代码 安装程序:带有mingw32的Win7,带有mingw32-pthreads-w32的g++4.8.1 pthread条件变量 解决方案: #包括 #包括 #包括 #包括 #包括 #包括 #包括//用于ostringstream #定义N_线程7 使用名称空间std; //原型 int main(); int调度器(); void*工作线程(void*ptr); 字符串原子输出(int my_int,int

pthread_cond_wake多线程示例

从线程0的某些广播中唤醒线程1和3的代码

安装程序:带有mingw32的Win7,带有mingw32-pthreads-w32的g++4.8.1 pthread条件变量

解决方案:

#包括
#包括
#包括
#包括
#包括
#包括
#包括//用于ostringstream
#定义N_线程7
使用名称空间std;
//原型
int main();
int调度器();
void*工作线程(void*ptr);
字符串原子输出(int my_int,int thread_id);
//全局变量
//pthread_t thread0、thread1、thread2、thread3、thread4、thread5、thread6、thread7;
pthread_t m_thread[N_thread];
整数计数=1;
pthread\u mutex\u t count\u mutex=pthread\u mutex\u初始值设定项;
pthread_cond_t condition_var=pthread_cond_初始值设定项;
//主要
int main(){
库特
注意:

  • 必须锁定互斥锁
  • 在等待之前,必须检查谓词(您正在等待的内容)
  • 等待必须在循环中

  • 违反这三条规则中的任何一条都会导致您所看到的问题。您的主要问题是,您违反了第二条规则,即使您想等待的事情已经发生,您仍在等待。

    我们可以看到代码吗?请看漂亮吗?直接在问题中添加了代码:)您可以搜索如何使用条件va的示例吗变量?或者询问如何使用它们,并省去一大堆与您的问题不相关的代码。我做到了,它们中没有一个适用于超过2个线程。在问题末尾添加了参考…有两个问题比较突出。第一个问题是您假设
    pthread\u t
    是整数类型。第二个问题是竞争-假设线程“0”将是第一个运行的线程,因此成功地首先锁定了
    计数互斥锁。为什么,如果您已经有了“整数”
    线程id
    ,那么在调用
    原子输出时,您会使用
    ptr
    (这个名字很奇怪,因为它没有输出)。你能编辑代码来演示如何操作吗?我理解你的意思,但这无助于我实现目标。我也理解cond_wait应该将时间回馈给cpu。因此,如果你(0)没有。另外,如果你试图获得锁,但失败了,它也会等待它,对吗?@Lazik好的,我假设得太多了。你根本没有条件变量。忘记你的代码。忘记你的问题。忘记我的答案。找到一些使用你理解的条件变量的示例代码。原因
    while(0)
    错误在于你必须等待一些东西。是的,我希望我可以,我在搜索它,但找不到任何符合我要求的东西。这就是我在这里发布的原因。也许我要找的不是条件互斥模式。@Lazik可能会帮到你。不,它不需要等待第二次广播。广播会通知线程它正在运行它可能已经发生了,但它不可能是线程正在等待的东西,因为它必须有一个状态(要么发生了,要么没有发生,所以有两个状态)而条件变量是无状态的。如果你在等待某件事,那么它要么已经发生了,要么还没有发生。不管发生了什么事,都必须存储在某个地方,以便你知道是否要等待。这件事被称为“谓词”,您必须实现它。条件变量的全部目的是提供一个原子“解锁并等待”操作,以修复在您尝试等待时发生的竞态条件。如果这一切对您来说都没有意义,您就无法充分理解条件变量,无法使用它们编写代码。
    #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;
    }
    
    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.
    
    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 );
        }
    
    pthread_mutex_lock(&mutex_associated_with_condition_variable);
    while (!predicate)
        pthread_cond_wait(&condition_variable, mutex_associated_with_condition_variable);