c / Какое поведение вы ожидаете, лучшую практику, сигнал, поток, процесс? - PullRequest
1 голос
/ 31 мая 2011

Мой источник выглядит так:

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 ]

2 голосов
/ 31 мая 2011

Прежде всего вы играете в опасную игру.Не особенно плохо, но стоит ли смешивать потоки, форк и сигналы?Я имею в виду, смешивание потоков и сигналов достаточно головной боли.Не могли бы вы решить эту проблему, используя только разветвления / только разметки ?

Во-вторых, на мой взгляд, сигналы - это слабый, архаичный механизм IPC.

Лучшие механизмы:

  • Очереди сообщений, семафоры (потоки и процессы)
  • Переменные условия (только потоки)

Я не знаю точную проблему, которую вы решаете, но вВ вашем случае я бы пошел с несколькими потоками и некоторыми условными переменными.

1 голос
/ 01 июня 2011

Я не понимаю следующего The variable keep_going is known by both processes, the child and the parent, что вы имеете в виду?Согласно вашему коду эта переменная не используется совместно процессами, поэтому если она изменяется в родительском, она не изменяется в дочернем.

Самый простой способ - отправить сигнал ребенку, когда родитель получил SIGUSR1.

Кроме того, подумайте дважды, когда используете сигналы, потоки и разветвление.

1 голос
/ 31 мая 2011

Обычный механизм для однобитовой межпотоковой связи (особенно для блокировки ресурсов) - через мьютексы. См. Этот простой пример .

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;
}
...