导致等待线程返回用户空间

时间:2015-11-16 17:56:32

标签: c linux multithreading mutex futex

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

  1. 我有一个获得futex锁的线程A" 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停止等待锁,并且 做点什么。

  4. 所以基本上,在这一点上,我试图弄清楚我是否可以制作线程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的返回值,并意识到调用没有返回。

1 个答案:

答案 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,...)
}