3

是否有可能唤醒正在等待 futex 锁的线程?我尝试使用信号机制,但它似乎不起作用。还有其他我可以尝试的方法吗?下面,我添加了一个可能与我想要实现的目标相似的示例。

  1. 我有一个线程 A 获取 futex 锁“lockA”,如下所示:- ret = syscall(__NR_futex, &lockA, FUTEX_LOCK_PI, 1, 0, NULL, 0);

  2. 我有一个线程 B 试图获取 futex 锁“lockA”,并在内核中阻塞,因为线程 A 已经获取了锁。 ret = syscall(__NR_futex, &lockA, FUTEX_LOCK_PI, 1, 0, NULL, 0);

  3. 如果线程 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");
}

从线程 CI 尝试将信号发送为:- pthread_kill(tid_of_B, SIGSYS);

我究竟做错了什么?线程B可以被唤醒吗?如果是这样,我应该使用另一种方法吗?

[编辑] 根据下面的评论,我尝试检查 pthread_kill 的返回值并意识到调用没有返回。

4

1 回答 1

0

一些东西。

您使用FUTEX_LOCK_PI的是手册页中没有的。我刚刚查看了内核源代码和文档,看来此版本仅用于内核本身。它用于实现“PI mutex”作为内核的替代品spinlock

如果使用 a 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,...)
}
于 2015-11-16T21:03:21.690 回答