【问题标题】:Is a pthread condition variable one time use only?pthread 条件变量是否只能使用一次?
【发布时间】:2018-10-08 17:56:53
【问题描述】:

我正在学习使用 pthread、互斥锁和条件变量,但事情并没有按预期进行。

主线程:连续运行,向工作线程发出信号,从 file_A 读取。

工作线程:睡眠直到收到信号,写入 file_A,返回睡眠(应该是可重复的)

所以我知道这里需要一个互斥锁来防止两个线程读取/写入同一个文件。我正在使用条件变量向工作线程发出信号。

但由于某种原因,工作线程只运行一次。我需要重置条件变量还是做其他事情?

工作线程函数:

void* WriteTime(){
    pthread_mutex_lock(&mutex);
    pthread_cond_wait(&condition, &mutex);

    /* Open File, Write to File, Close File */

    pthread_mutex_unlock(&mutex);
}

主线程:

pthread_t timeThread;
pthread_create(&timeThread, NULL, &WriteTime, NULL);

while(gameConditionFulfilled == false){
    /* Print status, gets user input into line */

    /* If user enters "time", wake up WORKER_THREAD */

    if(strcmp(line, "time")==0){
        pthread_mutex_lock(&mutex);
        pthread_cond_signal(&condition);

        /* Read from file, print data, close file */ 

        pthread_mutex_unlock(&mutex);
    }
}

另外我对上面代码的理解是这样的:

  1. 工作线程锁定互斥锁。 (在主循环之前启动)
  2. 工作线程 cond_wait 解锁互斥锁并等待条件。
  3. 主线程锁定互斥体。
  4. 主线程发出信号条件。
  5. 工作线程重新获得互斥锁,写入文件。
  6. 工作线程解锁互斥锁。
  7. 主线程重新获得互斥体并将其锁定。
  8. 主线程读取文件。
  9. 主线程解锁互斥锁。
  10. 工作线程重新获得锁定?

行为其实是:

  1. 主线程从文件中读取
  2. 工作线程唤醒,写入文件,不再运行

【问题讨论】:

    标签: c multithreading pthreads mutex condition-variable


    【解决方案1】:

    首先,您需要在 WriteTime() 中进行某种循环——返回会导致调用 pthread_exit()。当 pthread_create() 启动一个线程时,它的启动方式如下:

    pthread_exit((*func)(arg));
    

    这就引出了第二点——你的编译器应该对你大喊大叫,因为你的 WriteTime() 没有返回任何东西。警告很有用;它们不需要被服从,但你应该明白它们为什么会出现。

    跳过几章,条件变量的概念是保护“条件”;例如,有数据准备好读取或写入。您可以像使用信号量一样使用它们,但与信号量不同的是,条件变量没有任何内存。只有当线程正在等待时调用 pthread_condition_(signal|broadcast)(),Pthread_condition_wait() 才会返回。如果在无人等待时调用 pthread_condition_signal(),则不会发生任何事情。所以条件变量的惯用用法是:

    lock(mutex)
    while (something_hasn’t_happened) {
        wait(cond, mutex)
    }
    do something
    unlock(mutex)
    

    【讨论】:

    • 感谢您的帮助,我想通了。我的 WriteTime() 运行一次并退出。顺便说一句,gcc -Wall 有零编译警告。该函数是 void * 并且似乎不需要返回。
    猜你喜欢
    • 2021-08-24
    • 2011-03-23
    • 1970-01-01
    • 2014-01-13
    • 2011-02-11
    • 1970-01-01
    • 2016-06-18
    • 2019-04-05
    相关资源
    最近更新 更多