gpt4 book ai didi

c - Pthread 条件信号 - 未按预期工作

转载 作者:太空狗 更新时间:2023-10-29 14:50:13 28 4
gpt4 key购买 nike

我正在做一个项目并尝试使用 pthread_cond_wait()pthread_cond_signal() 来同步两个线程。

我的代码看起来像这样:

pthread_mutex_t lock_it = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t write_it = PTHREAD_COND_INITIALIZER;

int main(int argc, char**argv)
{

pthread_t t_send_segments, t_recv_acks;

pthread_create(&t_send_segments, NULL, send_segments, (void*)NULL);
pthread_create(&t_recv_acks, NULL, recv_acks, (void*)NULL);

pthread_join(t_recv_acks, (void**)NULL);

pthread_mutex_destroy(&lock_it);
pthread_cond_destroy(&write_it);
}

void* send_segments(void *v) {
for(;;) {
pthread_mutex_lock(&lock_it);
printf("s1\n");
printf("s2\n");
pthread_cond_wait(&write_it, &lock_it);
printf("s3\n");
printf("s4\n");
printf("s5\n");
pthread_mutex_unlock(&lock_it);
}
return 0;
}

void* recv_acks(void *v) {
for(;;) {
pthread_mutex_lock(&lock_it);
printf("r1\n");
pthread_cond_signal(&write_it);
printf("r2\n");
pthread_mutex_unlock(&lock_it);
}
return 0;
}

预期的输出是:

s1
s2
r1
s3
s4
s5
s1
s2
r2
r1
s3
s4
s5

(etc)

我的输出根本不遵循这种模式。显然我在某处有逻辑错误,但我不明白在哪里。为什么 recv_acks() 线程在遇到 pthread_cond_signal()总是 产生 - 因为 pthread_cond_wait() 总是首先执行(因为我创建线程的顺序)并且 cond_wait() 总是在临界区执行?

最佳答案

pthread_cond_signal 函数不会导致当前线程让步,也不会释放互斥量。它所做的只是重新启动一个通过 pthread_cond_wait 挂起的线程。这只是意味着唤醒的线程可用于调度,它不会立即执行。线程调度程序将在未来的某个时间安排它。

另外,仅仅因为s-thread已经被唤醒并且正在争夺mutex,并不意味着它接下来会得到mutex。互斥量不一定对所有请求它的线程都是公平的。根据 pthread_mutex 手册页:“pthread_mutex_lock 锁定给定的互斥量。如果互斥量当前未锁定,则它被锁定并由调用线程拥有,并且 pthread_mutex_lock 立即返回。”所以 r-thread 可以在它的循环中旋转几次,在被调度程序换出之前愉快地解锁和重新锁定互斥体几次。这意味着如果调度程序在释放互斥锁的短暂时间内恰好中断了 r 线程,则 s 线程将只有机会获得互斥锁。

为了获得您想要的输出,两个线程都需要使用一个条件来控制它们的执行,并在挂起它们之前互相发出信号。但是,这可能是也可能不是您实际想要对实际项目执行的操作。

另一个注意事项:创建线程的顺序并不重要。创建线程不会产生创建线程。所以主线程可能会在任何一个被调度之前创建两个线程,并且线程调度器可以自由地调度其中一个以供接下来执行。如果 s-thread 确实首先在您的平台上运行,那只是恰好是您平台上的实现行为,而不是应该依赖的东西。

关于c - Pthread 条件信号 - 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/671199/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com