是否可以在多个条件下使用 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
但这在语义上是一样的,所以由你决定。
我有一个多线程程序,每个线程都专注于自己的工作。当一个线程完成它的工作时,它将把事件驱动到主线程。
所以想用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
但这在语义上是一样的,所以由你决定。