c /您期望的行为,最佳实践,信号,线程,流程?

时间:2011-05-31 12:31:47

标签: c pthreads fork signals

我的来源看起来像这样:

keep_going = 1;
struct sigaction action;
memset(&action, '\0', sizeof(action));
action.sa_sigaction = &signal_handler;

if (sigaction(SIGUSR1, &action, NULL) < 0) {
    perror ("sigaction\n");
    return 1;
}

pid_t cpid = fork();

if(cpid == 0)
{
    // child process
    child_process(&p_config_0);
}
else if (cpid < 0)
{
    perror("fork not successful\n");
}
else
{
    // parent process
    pthread_t mgmt_tid;
    int rc_1 = pthread_create(&mgmt_tid, NULL, mgmtSrvcThread, (void *) &p_config_0);

    if(rc_1)
    {
        printf("error: pthread_create() is %d\n", rc_1);
        exit(1);
    }

    parent_process(&p_config_0);
}

void signal_handler(int sig, siginfo_t *siginfo, void *context)
{
    printf("signal received: %d\n", sig);
    printf("waiting until configuration is done\n");
    keep_going = 0;
    sleep(5);
    printf("done\n");
    keep_going = 1;
}

变量keep_going由两个进程(子进程和父进程)都知道。 父母在开始正常工作之前启动另一个线程。此线程正在侦听管理信息,并将keep_going设置为false以停止工作进程,父进程和子进程。它工作但感觉不对,实际上我并不确定背后的是什么......

当我在分叉之前安装信号处理程序时,我认为在分叉之后会有两个,一个用于父级,一个用于孩子,对吧?信号处理程序设置控制两个进程中while(keep_going)循环的变量。

我现在的问题是,我希望执行mgmtSrvcThread方法的线程在引发raise(SIGUSR1)时停止这两个进程。当在线程内完成配置时,两个进程都应该继续工作。也许可以发送第二个信号或设置超时。从一个线程控制两个进程的最佳方法是什么。

我很乐意得到任何帮助。 提前致谢。 nyyrikki

3 个答案:

答案 0 :(得分:2)

首先,你正在玩一个危险的游戏。不是特别糟糕,但是真的值得混合线程,叉子和信号吗?我的意思是,混合线程和信号就足够了。难道你不能用只是forks /只是pthreads 来解决这个问题吗?

其次,在我看来,信号是一种糟糕的,陈旧的IPC机制。

更好的机制:

  • 消息队列,信号量(线程和进程)
  • 条件变量(仅限线程)

我不知道您正在解决的确切问题,但在您的情况下,我会使用一些线程和一些条件变量。

答案 1 :(得分:1)

单比特跨线程通信(特别是资源锁定)的常用机制是通过互斥锁。 See this simple example

void *theThread(void *parm)
{
   int   rc;
   printf("Thread %.8x %.8x: Entered\n", pthread_getthreadid_np());
   rc = pthread_mutex_lock(&mutex);
   checkResults("pthread_mutex_lock()\n", rc);
   /********** Critical Section *******************/
   printf("Thread %.8x %.8x: Start critical section, holding lock\n",
      pthread_getthreadid_np());
   /* Access to shared data goes here */
   ++sharedData; --sharedData2;
   printf("Thread %.8x %.8x: End critical section, release lock\n",
          pthread_getthreadid_np());
   /********** Critical Section *******************/
   rc = pthread_mutex_unlock(&mutex);
   checkResults("pthread_mutex_unlock()\n", rc);
   return NULL;
}

答案 2 :(得分:1)

我不明白下一个The variable keep_going is known by both processes, the child and the parent,你的意思是什么?根据您的代码,此变量不在进程之间共享,因此如果在父进程中更改它,则不会在子进程中更改它。

最简单的方法是在父母得到SIGUSR1时向孩子发送信号。

另外,在使用信号,线程和分叉时请三思而后行。