我使用 eCos 开发嵌入式系统: 我在同一进程中有 2 个线程和 1 个信号量。
- 线程 A 将信号量初始化为 0,以便第一次尝试获取信号量时将被阻止。
- 线程 A 向线程 B 发送命令,并提供回调。
- 线程 A 使用
sem_timedwait
等待信号量 - 线程 B 处理命令并递增信号量
- 线程 A 应该被唤醒,但仍处于阻塞状态
这是代码:
线程A
static sem_t semaphore;
void callback()
{
// Do some stuff
int ret = sem_post(&semaphore);
// print confirmation message
}
void foo()
{
int ret = sem_init(&semaphore, 0, 0);
if(ret != 0)
{
// print errno
}
struct timespec ts;
clock_gettime(CLOCK_REALTIME,&ts); // Get current date
ts.tv_sec += 2; // Add 2s for the deadline
send_command_to_thread_B(&callback);
ret = sem_timedwait(&semaphore, &ts);
if(ret != 0)
{
// print errno
}
// print waking up message
}
线程 B 中的内容不相关。
为了调试,我尝试了以下方法:
- 使用
sem_wait
而不是sem_timedwait
有效:线程A被阻塞,然后在回调后解锁。但我不想使用它,因为如果回调过程中出现故障导致信号量无法递增,线程 A 将永远等待。 - 如果我不将 2 添加到
timespec
结构中,sem_timedwait
会立即返回,并且errno
设置为ETIMEDOUT
(似乎合法)。回调已被调用,但对于线程 A 来说为时已晚。 - 我在回调调用中放置了跟踪,以确保信号量确实从 0 递增到 1:所有过程都已完成,回调退出,但线程 A 仍处于阻塞状态。
你们有什么线索吗?我错过了什么吗?
最佳答案
好吧,实际上这段代码一切都很好,问题出在其他地方:我遇到了导致死锁的重新进入问题。
寓意:在多线程上下文中小心保护您的资源和地址
关于c - 为什么 sem_timedwait() 没有醒来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22346340/