0

我正在开发一个将在嵌入式 ARM Linux 上运行的软件。它使用 Posix 线程并且在为我的计算机编译时运行良好。但是一旦我交叉编译它,我就会看到奇怪的线程问题:

  1. 分离的线程和连接的线程在返回时不会退出。我仍然可以在进程列表中看到它们。它们只有在主线程退出时才会消失。

  2. 信号以一种奇怪的方式处理。我知道信号在线程中可能很棘手,所以我将它们全部阻止,只允许它们在正确处理它们的线程中。但是在我的 ARM 机器上,这个线程无法捕捉到任何信号。

这个 ARM 盒子里的系统已经过时了,它使用 Linux 2.6.9,我的工具链是 GCC 3.3.2。有人知道此类系统上 Posix 线程的某种限制吗?


这是我处理信号的一些代码:

/**
*   Thread that just waits for signals to catch
*/
static void *signals(void *arg) {

    sigset_t *set = (sigset_t *) arg;
    int sig;

    if (pthread_sigmask(SIG_UNBLOCK, set, NULL))
        warnx("Cannot unblock signals");

    while (program_should_continue()) {

        /* wait for a signal */
        if (sigwait(set, &sig))
            warnx("Could not handle signal");

        switch (sig) {

            /* Do stuff */
        }
    }

    return NULL;

}

线程的创建:

int main(int argc, char **argv) {

    /* set the signals to be bocked for threads */
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGQUIT);
    sigaddset(&sigset, SIGTERM);
    sigaddset(&sigset, SIGINT);
    sigaddset(&sigset, SIGALRM);
    if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
        errx(EXIT_FAILURE, "Cannot block signals for new threads");

    /* set attributes for detached threads */
    pthread_attr_init(&detached_attr);
    pthread_attr_setdetachstate(&detached_attr, PTHREAD_CREATE_DETACHED);

    /* create signal thread */
    if (pthread_create(&pth_signals, &detached_attr, signals, (void*) &sigset)) {
        errx(EXIT_FAILURE, "Cannot create thread signals");
    } else {
        if (pthread_setname(pth_signals, "signals"))
            warnx("Cannot set thread name");
    }

}
4

2 回答 2

4

我唯一能想象的是,在非常旧的系统上使用LinuxThreads而不是 NPTL,后者是 Linux 上 pthreads 的当前实现。LinuxThreads 有许多问题,特别是与信号处理有关的问题。从LinuxThreads 常见问题解答中,

如果信号是通过 kill() 或 tty 接口(例如通过按 ctrl-C)发送的,则 POSIX 规范说处理程序由当前不阻塞信号的进程中的任何线程执行。换句话说,POSIX 认为信号是作为一个整体发送给进程(所有线程的集合)的,任何没有阻塞这个信号的线程都可以处理它。

后一种情况是 LinuxThreads 偏离 POSIX 规范的地方。在 LinuxThreads 中,没有真正的“整个进程”的概念:在内核中,每个线程实际上都是具有不同 PID 的不同进程,发送到线程 PID 的信号只能由该进程处理线。只要没有线程阻塞信号,行为就符合标准:程序的一个(未指定)线程处理信号。但是如果信号被发送到 PID 的线程阻塞了信号,而其他一些线程没有阻塞信号,那么 LinuxThreads 将简单地在该线程中排队并仅在该线程解除阻塞信号时执行处理程序,而不是执行处理程序立即在不阻塞信号的另一个线程中。

这将被视为一个 LinuxThreads 错误,但我目前看不到没有内核支持来实现 POSIX 行为的任何方法。

于 2013-07-05T09:11:37.197 回答
1

你有旧的LinuxThreads实现而不是新的 NPTL 实现。在 PosixThreads 下,信号完全被错误处理——每个线程都有自己的 PID,并且表现得像一个进程。

于 2013-07-05T09:11:23.177 回答