【发布时间】:2016-02-17 22:08:14
【问题描述】:
是否可以唤醒正在等待 futex 锁的线程?我试过了 使用信号机制,但它似乎不起作用。有没有其他方法 我可以试试吗?下面,我添加了一个可能与我类似的示例 努力实现。
我有一个线程 A 获取 futex 锁“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 的返回值,发现调用没有返回。
【问题讨论】:
-
理论上,我认为向它发送信号应该可以工作。如果你让线程忙等待或
sleep(),然后发送信号,你的处理程序会被调用吗? -
我建议不要在信号处理程序中调用异步不安全函数,即使是调试也是如此。如果你真的需要记录你的信号处理程序的调用,
write()到STDERR_FILENO。 -
对
pthread_kill()的调用返回哪个值? -
另外,如果你做进行系统调用,你应该使用
futex()库函数包装器。 -
您是否考虑过使用普通的 pthreads 互斥锁而不是 futex?正如文档所说,“裸 futexes 并不是最终用户易于使用的抽象”。我强烈建议您首先让您的系统尽可能简单地工作。只有当速度不够快时,您才应该考虑使用 futexes 或其他深奥的技术来加快速度。即便如此,找到一种更好的算法通常比调整现有算法以加快速度更有优势。
标签: c linux multithreading mutex futex