C:关机的多线程程序

C:关机的多线程程序

问题描述:

的想法是有其启动多个工作线程一个主线程。除了发送信号之外,没有明确的方式退出程序。但是程序也应该在任何地方发生错误时干净地退出。C:关机的多线程程序

我试图表明我有什么至今。标题没有显示,但没有它们应该清楚。我们有一个主函数main.c,其中main函数开始于worker.c,它具有线程管理和object.c的抽象,一个工作线程的特定实现。将会有多种不同的实现,但都具有相同的结构(即,具有while(running)循环的process()函数)。

的main.c

#include <signal.h> 

#define NUM_THREADS 5 

volatile static sig_atomic_t running = 1; 
volatile static int exit_code = 0; 

void shutdown(int s) 
{ 
    running = 0; 
    exit_code = s; 
} 

int main(int argc, char **argv) 
{ 
    struct sigaction sa; 
    sa.sa_handler = shutdown; 
    sigaction(SIGINT, &sa, 0); 

    thread_obj *threads[NUM_THREADS]; 
    for (int i = 0; i < NUM_THREADS; ++i) { 
     threads[i] = worker_new(); 
    } 


    for(int i = 0; i < NUM_THREADS; ++i) { 
     pthread_join(threads[i]->worker, NULL); 
     theads[i]->free(); 
     free(threads[i]); 
    } 

    return exit_code; 
} 

worker.c

#include <pthread.h> 

struct thread_object { 
    pthread_t worker; 
    int *running: 
    void *obj; 
    void (*process)(void *obj, int *running); 
    void (*free)(void *obj); 
}: 

void *thread_func(void *obj) 
{ 
    struct thread_object *tmp = obj; 
    tmp->process(tmp->obj, tmp->running): 
    return; 
} 

struct thread_object *worker_new(void *obj) 
{ 
    struct thread_object *tmp = malloc(sizeof(*tmp)); 
    tmp->obj = obj; 
    tmp->running = running; 
    tmp->process = obj->process; 
    tmp->free = obj->free; 
    pthread_create(&(tmp->worker), NULL, thread_func, obj); 
    return tmp; 
} 

object.c

#include "main.h" 

void process(void *obj, int *running) 
{ 
    struct special_object *tmp = obj; 
    while(*running) { 
     // do something 
     if(error) { 
      kill(getpid(), SIGTERM); 
      break; 
     } 
    } 
    // cleanup tasks 
} 

现在的问题是,这将是最干净,最快捷,最简便的方式在C中实现这一点?两个要点:停止所有线程并正常关闭,如果a)收到SIGINT等信号或者b)至少有一名员工遇到错误。

编辑:我想包括的建议,但现在也有一些后续问题:

  • 在pthread_join更多/更少/同等有效的睡眠?主要 线程无关而工人来看,只有赶上信号, 和我想避免尽可能多的唤醒越好。
  • 考虑以下几点:我们赶上SIGTERM信号处理程序的 running变量设置为false。这会跳过循环(可靠)吗?

kill(getpid(), SIGTERM); while (*running) {;}

+0

“停止所有线程和正常关机”好,你应该明白,这是,在一般情况下,通常可用的语言/ OS,如不可能的。 C在Windows/Linux上。如果完全可能,您应该设计以便在进程终止/重新启动时正确运行'停止所有线程并正常关闭'。 –

+0

它看起来像你已经显示的代码已经符合大部分要求;有没有一些特别的方法可以缩短? (如果你想让关闭序列在特定线程遇到错误时也发生,最简单的方法就是让线程调用例如kill(getpid(),SIGINT),以便线程发送一个信号给它的包含进程;然后正常的信号处理序列将照常进行,以便以受控方式退出进程) –

+0

我不满意的一件事是主循环。我可能可以使用'pause()'而不是'sleep()',如果遇到错误发送一个信号,这个循环会中断。 仅仅调用'exit()'是不够的,因为我遇到了使用库的问题,至少有一些清理是绝对必要的。我很满意一个干净的解决方案,可以在99%的时间内工作。我所展示的代码只是一种设计方法,我希望得到反馈,在那里我可以改进或者可能出现错误。 – flowit

在这种情况下,睡眠循环是不需要的,连接应该够了。

在其他使用情况你可以看看waitpid函数为-1的PID从该有话要说任何线程获取状态。

如果某些线程在其他线程之前停止,在某些情况下可能会有用,或者在线程发布后执行某些操作,或者等到所有线程都发布后再执行某些操作。

+0

谢谢,我试图包含你的建议。看我的编辑。另外,您能否详细说明在什么情况下需要信号量?什么线程结束,线程是相互独立的,我不能做任何假设。设置全局运行变量应该是一个原子操作,所以我目前看不到有任何信号需要,但我可能会错过一些东西。 – flowit

+0

信号量可以等待一段时间,或者等到给定数量的信息发送给它,或者只是处理每个信息并评估是否要关闭它。 – Surt