终止具有关键部分代码的POSIX多线程应用程序的最佳方法是什么?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了终止具有关键部分代码的POSIX多线程应用程序的最佳方法是什么?相关的知识,希望对你有一定的参考价值。

我正在开发的应用程序碰巧是多线程的,每个线程都有一个关键的段代码。当用户中断应用程序时,我需要终止线程并保存执行状态,然后再终止应用程序。为此,我在线程函数中的随机位置编写了一些检查代码。以下是有助于理解执行流程的最小代码。

#include<pthread.h>
#include<signal.h>
#include<stdlib.h>

struct thread_data

    int quit;
    /* other data variables */
;

void* thread_func(void* data)


    for ( ; ; )
    

        /* Non critical section code start */

        if (((struct thread_data*) data)->quit)   // checks at random places
            pthread_exit(NULL);

        /* end */

        if (((struct thread_data*) data)->quit)
            pthread_exit(NULL);

        /* Critical section code start */

            // Use data structure.

        /* end */

        if (((struct thread_data*) data)->quit)
                pthread_exit(NULL);
    


int main()

    sigset_t sigmask;
    sigemptyset(&sigmask);
    sigaddset(&sigmask, SIGINT);

    pthread_sigmask(SIG_BLOCK, &sigmask, NULL);  // SIGINT is blocked by all the threads.


    struct thread_data* data = calloc(5, sizeof(struct thread_data));
    pthread_t tids[5];

    for (int i = 0; i < 5; i++)     // initialize the threads.
        pthread_create(tids + i, NULL, thread_func, (void*) (data + i));

    int signo;
    sigwait(&sigmask, &signo);  // wait for user interrupt.

    for (int i = 0; i < 5; i++)     // terminate threads.
    
        data[i].quit = 1;
        pthread_join(tids[i], NULL);
    

    /* Save the execution state */

        // Use data structure variable

    return 0;

但是这种方法似乎并不熟练,当thread_func扩大规模时,将这些检查放在多个位置会变得很累。值得一提的是,我不能依靠信号处理和从信号处理程序中调用pthread_exit(),因为它不是async-signal-safe function。有没有更好的方法来实现这一目标?

答案

可能不是您要查找的内容,也不是真正具有开创性的东西。但是要删除一些文本(因为我同意看起来有点混乱),至少要声明一个指针,而不要一直转换。

void* thread_func(void* data)

    struct thread_data *d = (struct thread_data*) data;

    if(d->quit) pthread_exit(NULL);

如果您经常进行这些检查,这将使它更整洁。您甚至可以使用int *quit = &d->quit使其更加干净,但这也许是过大了。

或使用函数或宏:

void maybe_quit(int x) 

    if(x) pthread_exit(NULL);


#define MAYBE_QUIT do   if (((struct thread_data*) data)->quit) \
                             pthread_exit(NULL);                \
                   while(0)

不是真正的创新方法,但是肯定会使代码看起来更简洁。

以上是关于终止具有关键部分代码的POSIX多线程应用程序的最佳方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章

POSIX 多线程程序设计

POSIX 多线程编程及理解

Linux多线程的创建等待终止

Linux操作系统多线程

Linux多线程

Linux 多线程