这是我为理解信号量语义而编写的一些代码:
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
sem_t sem;
void *helper(void *arg) {
sem_wait(&sem);
printf("helper woke up\n");
}
int main() {
sem_init(&sem, 0, 0);
pthread_t tid;
pthread_create(&tid, NULL, helper, NULL);
sleep(1);
sem_post(&sem);
sem_wait(&sem);
printf("main woke up\n");
exit(0);
}
为什么打印这个
main woke up
而不是这个?
helper woke up
如果我们查看手册页,就会发现
如果信号量的值因此变得大于零,那么 在 sem_wait(3) 调用中阻塞的其他进程或线程将被唤醒并继续锁定信号量。
那么为什么允许主线程而不是辅助线程继续进行呢?
我在 Linux 上尝试了这段代码,得到了和你一样的结果。
但是当我使用gdb一步步调试这段代码时,我发现终端上打印了
helper woke up
,然后主线程将永远等待。
所以我认为这可能是一个未定义的行为,因为主线程永远不会进入 printf 函数,并且 main 函数永远不会退出。所以可能会涉及到一些奇怪的系统机制。
你可以删除主函数中最后一个
sem_wait(&sem);
,就会得到这样的结果。
helper woke up
main woke up