是否可以唤醒正在等待futex锁定的线程?我试过了 使用信号机制但它似乎不起作用。还有其他的方法吗? 我可以尝试一下吗?下面,我添加了一个可能类似于我的例子 试图实现。
我有一个获得futex锁的线程A" lockA"如下 :-
ret = syscall(__NR_futex, &lockA, FUTEX_LOCK_PI, 1, 0, NULL, 0);
我有一个线程B试图获取futex锁" lockA"和内核中的块,
因为线程A获得了锁定。
ret = syscall(__NR_futex, &lockA, FUTEX_LOCK_PI, 1, 0, NULL, 0);
如果线程B确实获得了lockA,另一个线程,线程C将知道它。如果是线程B. 没有获得锁,线程C希望线程B停止等待锁,并且 做点什么。
所以基本上,在这一点上,我试图弄清楚我是否可以制作线程C"信号"线程B. 这样它就不会再在内核中阻塞了。为了做到这一点,我设置了一个信号处理程序 线程B如下: -
struct sigaction act;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_restorer = NULL;
sigaction(SIGSYS, &act, NULL);
...
...
void handler() {
fprintf(stderr, "Inside the handler, outta the kernel\n");
}
从线程C我尝试发送信号为: -
pthread_kill(tid_of_B, SIGSYS);
我做错了什么?线程B可以被唤醒吗?如果是这样,我应该使用其他方法吗?
[编辑] 根据下面的评论,我尝试检查pthread_kill的返回值,并意识到调用没有返回。
答案 0 :(得分:0)
一些事情。
您正在使用手册页中不的FUTEX_LOCK_PI
。我刚刚查看了内核源代码和文档,看来这个版本只能在内核本身内部使用。它用于实现" PI互斥"作为内核spinlock
的替代。
如果使用futex
,则必须对其指向的地址中的数据实现语义。
这是一个原始的,伪代码,可能/可能是错误的例子:
int mysem = 1;
void
lock(void)
{
// atomic_dec returns new value
while (1) {
if (atomic_dec(&mysem) == 0)
break;
futex(&mysem,FUTEX_WAIT,...)
}
}
void
unlock(void)
{
// non_atomic_swap returns old value
if (non_atomic_swap(&mysem,1) != 0)
futex(&mysem,FUTEX_WAKE,...)
}