我观察到的行为似乎与 pthread_cond_signal
和 pthread_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/