在发出等待条件变量信号后,线程何时获取锁?什么决定了它?
After signaling a waiting condition variable, when the thread will acquire the lock? What determines it?
在网上搜索,并阅读Whosebug上的问题答案后,我找不到问题的答案。
等待在线程 B 中调用,它解锁互斥锁,允许其他人访问条件变量(用于发信号)。然后,当条件变量在线程 A 中发出信号时,线程 B 唤醒并且线程 B 再次锁定互斥锁。
当线程A通过向条件变量发送信号唤醒线程B时,线程B被唤醒,锁定互斥量。
我从教程中了解到,只要线程 B 收到信号,它就会立即锁定互斥量。然而示例与此相反,当线程 B 收到信号并被唤醒时,线程 A 继续执行,一段时间后线程 B 锁定互斥锁。
我的问题是线程 B(下例中的消费者)何时锁定互斥锁?就在线程 B 收到信号的那一刻?还是取决于线程调度器?
我没有找到任何相关解释。
我正在考虑以下示例的情况:
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
int buffer[100];
int loops = 5;
int length = 0;
void *producer(void *arg) {
int i,j;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex);
buffer[length++] = i;
printf("producer length %d\n", length);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
}
void *consumer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex);
while(length == 0) {
printf(" consumer waiting...\n");
pthread_cond_wait(&cond, &mutex);
}
int item = buffer[--length];
printf("Consumer %d\n", item);
pthread_mutex_unlock(&mutex);
}
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mutex, 0);
pthread_cond_init(&cond, 0);
pthread_t pThread, cThread;
pthread_create(&pThread, 0, producer, 0);
pthread_create(&cThread, 0, consumer, 0);
pthread_join(pThread, NULL);
pthread_join(cThread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
输出:
consumer waiting...
producer length 1
producer length 2
producer length 3
producer length 4
producer length 5
Consumer 4
Consumer 3
Consumer 2
Consumer 1
Consumer 0
在此先致谢
线程 B(消费者)醒来时已获得互斥量,假设 pthread_cond_unlock
returns 成功。所以你想检查 return 值(即 0 = 成功)以了解是否获取了互斥量。
条件变量的行为是释放锁并等待(原子地),然后在线程收到信号时重新获取锁。在您的代码中,一个线程在持有互斥量的同时向另一个线程发出信号,这意味着被唤醒的线程将进入互斥量中的等待队列,直到另一个线程释放互斥量。
关于使用 pthread 条件变量 + 互斥锁时不太明显的隐含行为,我只想在这里补充两分。考虑以下序列:
pthread_mutex_lock(&m);
pthread_con_wait(&cond,&m);
pthread_mutex_unlock(&m);
一旦线程在 'cond' 上等待,它也会自动解锁互斥量!!这并不明显,并且引起了很多混乱。
在网上搜索,并阅读Whosebug上的问题答案后,我找不到问题的答案。
等待在线程 B 中调用,它解锁互斥锁,允许其他人访问条件变量(用于发信号)。然后,当条件变量在线程 A 中发出信号时,线程 B 唤醒并且线程 B 再次锁定互斥锁。
当线程A通过向条件变量发送信号唤醒线程B时,线程B被唤醒,锁定互斥量。
我从教程中了解到,只要线程 B 收到信号,它就会立即锁定互斥量。然而示例与此相反,当线程 B 收到信号并被唤醒时,线程 A 继续执行,一段时间后线程 B 锁定互斥锁。
我的问题是线程 B(下例中的消费者)何时锁定互斥锁?就在线程 B 收到信号的那一刻?还是取决于线程调度器?
我没有找到任何相关解释。
我正在考虑以下示例的情况:
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
int buffer[100];
int loops = 5;
int length = 0;
void *producer(void *arg) {
int i,j;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex);
buffer[length++] = i;
printf("producer length %d\n", length);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
}
void *consumer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex);
while(length == 0) {
printf(" consumer waiting...\n");
pthread_cond_wait(&cond, &mutex);
}
int item = buffer[--length];
printf("Consumer %d\n", item);
pthread_mutex_unlock(&mutex);
}
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mutex, 0);
pthread_cond_init(&cond, 0);
pthread_t pThread, cThread;
pthread_create(&pThread, 0, producer, 0);
pthread_create(&cThread, 0, consumer, 0);
pthread_join(pThread, NULL);
pthread_join(cThread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
输出:
consumer waiting...
producer length 1
producer length 2
producer length 3
producer length 4
producer length 5
Consumer 4
Consumer 3
Consumer 2
Consumer 1
Consumer 0
在此先致谢
线程 B(消费者)醒来时已获得互斥量,假设 pthread_cond_unlock
returns 成功。所以你想检查 return 值(即 0 = 成功)以了解是否获取了互斥量。
条件变量的行为是释放锁并等待(原子地),然后在线程收到信号时重新获取锁。在您的代码中,一个线程在持有互斥量的同时向另一个线程发出信号,这意味着被唤醒的线程将进入互斥量中的等待队列,直到另一个线程释放互斥量。
关于使用 pthread 条件变量 + 互斥锁时不太明显的隐含行为,我只想在这里补充两分。考虑以下序列:
pthread_mutex_lock(&m);
pthread_con_wait(&cond,&m);
pthread_mutex_unlock(&m);
一旦线程在 'cond' 上等待,它也会自动解锁互斥量!!这并不明显,并且引起了很多混乱。