是否可以在多个条件下使用 pthread 条件变量(pthread_mutex 和 pthread_cond_t)?

Is it possible to use pthread conditon variable (pthread_mutex and pthread_cond_t )with multiple conditons?

我有一个多线程程序,每个线程都专注于自己的工作。当一个线程完成它的工作时,它将把事件驱动到主线程。

所以想用pthread条件变量来实现这个想法(即pthread_cond_t和pthread_mutex_t)。数据结构如下:

typedef struct peer_info {
    int ip; 
    int port;
    pthread_mutex_t peer_mutex;
    pthread_cond_t peer_cond;
    bool write_v;
    bool read_v;
    bool create_v;
    bool destroy_v;
} peer_info;

假设:
thread1 更改 write_v 并向主线程发出信号,
thread2 更改 read_v 并向主线程发出信号,
thread3 更改 create_v 并向主线程发出信号,
thread4 更改 destroy_v 并向主线程发出信号。

是否可以只用一个pthread_mutex和pthread_cond_t来实现上面的场景?会不会造成死锁?

是的,您可以安全地等待“复合谓词”,其中一个信号表示“这个状态改变了那个状态改变了 其他一些状态改变了 ..."

在您的情况下,这些状态是您设置的 event_v 标志。假设您的主线程处于循环中,并且 event_v 标志被初始化为 false,它看起来像这样:

// main loop:
pthread_mutex_lock(&pi.peer_mutex);
while (! (pi.write_v || pi.read_v || ... )) {
  pthread_cond_wait(&pi.peer_cond, &pi.peer_mutex);
}
if (pi.write_v) {
  pi.write_v = false; // clear this so we're not confused next time we wake up
  handle_write_event(&pi);
}
if (pi.read_v) {
  pi.read_v = false;
  handle_read_event(&pi);
}
if (...) ...          // handle other events

请注意,这将在互斥量被锁定时处理事件,这对您来说可能适合也可能不适合。

顺便说一句,我发现所有这些布尔标志有点麻烦,可能会改用位标志:

#define PEER_EVENT_READ  1 << 0
#define PEER_EVENT_WRITE 1 << 1
#define PEER_EVENT_ ...

struct peer_info {
  short events_pending; // initialized to zero
  ...
};

所以我可以简明扼要地写:

while (! pi.events_pending) {
  pthread_cond_wait(&pi.peer_cond, &pi.peer_mutex);
}
if (pi.events_pending & PEER_EVENT_READ) { ... }
if ....
pi.events_pending = 0; // clear them all

但这在语义上是一样的,所以由你决定。