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

问题描述 投票:2回答:1

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

#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。有没有更好的方法来实现这一目标?

c linux multithreading pthreads posix
1个回答
0
投票

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

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)

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

© www.soinside.com 2019 - 2024. All rights reserved.