multithreading - pthread_cond_signal 不会立即解锁 pthread_cond_wait 线程

标签 multithreading pthreads condition-variable

我观察到的行为似乎与 pthread_cond_signalpthread_cond_wait 的行为方式不一致(根据手册页)。 man 3 pthread_cond_signal规定:

The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).

这不够精确,也没有阐明调用 pthread_cond_signal 的线程是否会同时将其时间交还给调度程序。

这是一个示例程序:

     1  #include <pthread.h>
     2  #include <iostream>
     3  #include <time.h>
     4  #include <unistd.h>
     5
     6  int mMsg = 0;
     7  pthread_mutex_t mMsgMutex;
     8  pthread_cond_t mMsgCond;
     9  pthread_t consumerThread;
    10  pthread_t producerThread;
    11
    12  void* producer(void* data) {
    13      (void) data;
    14      while(true) {
    15          pthread_mutex_lock(&mMsgMutex);
    16          std::cout << "1> locked" << std::endl;
    17          mMsg += 1;
    18          std::cout << "1> sending signal, mMsg = " << mMsg << "" << std::endl;
    19          pthread_cond_signal(&mMsgCond);
    20          pthread_mutex_unlock(&mMsgMutex);
    21      }
    22
    23      return nullptr;
    24  }
    25
    26  void* consumer(void* data) {
    27      (void) data;
    28      pthread_mutex_lock(&mMsgMutex);
    29
    30      while(true) {
    31          while (mMsg == 0) {
    32              pthread_cond_wait(&mMsgCond, &mMsgMutex);
    33          }
    34          std::cout << "2> wake up, msg: " << mMsg << std::endl;
    35          mMsg = 0;
    36      }
    37
    38      return nullptr;
    39  }
    40
    41  int main()
    42  {
    43      pthread_mutex_init(&mMsgMutex, nullptr);
    44      pthread_cond_init(&mMsgCond, nullptr);
    45
    46      pthread_create(&consumerThread, nullptr, consumer, nullptr);
    47
    48      std::cout << "starting producer..." << std::endl;
    49
    50      sleep(1);
    51      pthread_create(&producerThread, nullptr, producer, nullptr);
    52
    53      pthread_join(consumerThread, nullptr);
    54      pthread_join(producerThread, nullptr);
    55      return 0;
    56  }

这是输出:

starting producer...
1> locked
1> sending signal, mMsg = 1
1> locked
1> sending signal, mMsg = 2
1> locked
1> sending signal, mMsg = 3
1> locked
1> sending signal, mMsg = 4
1> locked
1> sending signal, mMsg = 5
1> locked
1> sending signal, mMsg = 6
1> locked
1> sending signal, mMsg = 7
1> locked
1> sending signal, mMsg = 8
1> locked
1> sending signal, mMsg = 9
1> locked
1> sending signal, mMsg = 10
2> wake up, msg: 10
1> locked
1> sending signal, mMsg = 1
1> locked
1> sending signal, mMsg = 2
1> locked
1> sending signal, mMsg = 3
...

似乎无法保证任何 pthread_cond_signal 确实会立即解锁任何等待的 pthread_cond_wait 线程。同时,在发出第一个信号后,似乎任何数量的 pthread_cond_signal 都可能会丢失。

这真的是预期的行为还是我在这里做错了什么?

最佳答案

这是预期的行为。 pthread_cond_signal不会产生剩余的运行时间,但会继续运行。

是的,pthread_cond_signal 将立即解除阻塞(一个或多个)等待相应条件变量的线程。但是,这并不能保证所述等待线程会立即运行。它只是告诉操作系统该线程不再被阻塞,并且由操作系统线程调度程序决定何时开始运行它。由于信号线程已经在运行,在缓存中很热等,因此在现在已解除阻塞的线程开始执行任何操作之前,它可能有足够的时间执行某些操作。

在上面的示例中,如果您不想跳过消息,也许您正在寻找类似生产者-消费者队列之类的东西,可能由环形缓冲区支持。

关于multithreading - pthread_cond_signal 不会立即解锁 pthread_cond_wait 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68097292/

相关文章:

c++ - 从 int 到 void * 的转换是可能的吗?

multithreading - 负载平衡SOAP请求

c++ - std::unique_lock 和 std::condition_variable 如何工作

android - 停止线程的安全方法 - Android

c# - 对 List<Socket> 的多次访问

c - pthread_create空间不足

C++ Linux 错误加载共享库 `undefined symbol: pthread_create`

c - 当使用free()时,内存使用不会减少

multithreading - pthread_cond_timedwait 超时后线程是否拥有互斥锁?

c++ - 线程安全队列C++