Pthreads在旧ARM Linux上的处理方式是否相同?

时间:2013-07-05 09:01:45

标签: c multithreading pthreads

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

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

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

  3. 此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");
        }
    
    }
    

2 个答案:

答案 0 :(得分:4)

我唯一可以想象的是,在非常旧的系统LinuxThreads上使用的是NPTL,这是Linux上pthreads的当前实现。 LinuxThreads存在许多问题,特别是与信号处理有关的问题。来自LinuxThreads FAQ

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

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

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

答案 1 :(得分:1)

您拥有旧的LinuxThreads实施,而不是较新的NPTL实施。信号在PosixThreads下完全错误处理 - 每个线程都有自己的PID,行为就像一个进程。