Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: Проблема с сигналами  (Прочитано 1645 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн miksayer

  • Автор темы
  • Любитель
  • *
  • Сообщений: 59
    • Просмотр профиля
Проблема с сигналами
« : 19 Апрель 2010, 23:50:59 »
Добрый день! Делаю лабораторную работу по сигналам и столкнулся с проблемой. Вот мой код:
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

pid_t child_1 = 0, child_2 = 0;

void sighandler(int nsig)
{
  printf("test\n");
}

int main()
{
  //создаю 2 дочерних процесса и переопределяю для них обработчики сигналов
  child_1 = fork();
  if (child_1 == 0)
  {
    struct sigaction act;
    act.sa_handler = sighandler;
   
    sigaction(SIGUSR1, &act, 0);
  }
  else if (child_1 > 0)
  {
    child_2 = fork();
    if (child_2 == 0)
    {
      struct sigaction act;
      act.sa_handler = sighandler;
   
      sigaction(SIGUSR1, &act, 0);
    }
  }
  //посылаю из родительского процесса сигналы дочерним
  if (child_1 > 0 &&  child_2 > 0)
  {
    kill(child_2, SIGUSR1); sleep(2);
    kill(child_1, SIGUSR1); sleep(2);
  }
  return 0;
}
По идее должно два раза вывестись тестовое сообщение, но этого не происходит. Почему? И что делать?

Оффлайн _yk

  • Новичок
  • *
  • Сообщений: 13
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #1 : 20 Апрель 2010, 00:27:36 »
Дочерние процессы завершаются, не получив сигнала. Простейший выход - поставить pause(), плюс еще задержка нужна, ну а вообще конечно лучше по человечески синхронизировать)
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

pid_t child_1 = 0, child_2 = 0;

void sighandler(int nsig)
{
  printf("test\n");
}

int main()
{
  //создаю 2 дочерних процесса и переопределяю для них обработчики сигналов
  child_1 = fork();
  if (child_1 == 0)
  {
    struct sigaction act;
    act.sa_handler = sighandler;
   
    sigaction(SIGUSR1, &act, 0);
    pause();
  }
  else if (child_1 > 0)
  {
    child_2 = fork();
    if (child_2 == 0)
    {
      struct sigaction act;
      act.sa_handler = sighandler;
   
      sigaction(SIGUSR1, &act, 0);
      pause();
    }
  }
  //посылаю из родительского процесса сигналы дочерним
  if (child_1 > 0 &&  child_2 > 0)
  {
    sleep(1); //для уверенности, что дочерний процесс успел добавить обработчик
    kill(child_2, SIGUSR1); sleep(1);
    kill(child_1, SIGUSR1); sleep(1);
  }
  return 0;
}

Оффлайн miksayer

  • Автор темы
  • Любитель
  • *
  • Сообщений: 59
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #2 : 20 Апрель 2010, 15:18:33 »
спасибо за ответ. А как по-человечески синхронизировать? :-)
Вообще суть лабы заключается в том, что родительский процесс и два дочерних поочередно обмениваются сигналами через каждые 100 мс. При этом нужно предусмотреть механизм определения родителем, от какого из детей пришел сигнал. Последнее наверное буду делать через siginfo_t, сравнивая pid'ы дочерних процессов и процесса, от кооторого пришел сигнал. Или это можно как-то попроще сделать?

Пользователь решил продолжить мысль 20 Апрель 2010, 17:21:34:
Так, возникла еще одна проблема. Вот код:
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

pid_t child_1 = 0, child_2 = 0;

void sighandler(int nsig)
{
  printf("child\n");
  kill(getppid(), SIGUSR2);
 // sleep(1);
  pause();
}

void psighandler(int nsig, siginfo_t * si, void * b)
{
  printf("pid: %d 1: %d 2: %d\n", si->si_pid, child_1, child_2);
  usleep(1000);
  printf("%d\n", kill(child_2, SIGUSR1));
  printf("%d\n", kill(child_1, SIGUSR1));
  pause(); 
}

int main()
{
 
  child_1 = fork();
  if (child_1 == 0)
  {
    struct sigaction act;
    act.sa_handler = sighandler;
    sigaction(SIGUSR1, &act, 0);
    pause();
  }
  else if (child_1 > 0)
  {
    child_2 = fork();
    if (child_2 == 0)
    {
      struct sigaction act;
      act.sa_handler = sighandler;
   
      sigaction(SIGUSR1, &act, 0);
      pause();
    }
  }
 
  if (child_1 > 0 &&  child_2 > 0)
  {
    struct sigaction act;
    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = psighandler;
    sigaction(SIGUSR2, &act, 0);
   
    sleep(1);
    kill(child_2, SIGUSR1);
    kill(child_1, SIGUSR1);
    pause();
  }
  return 0;
}
По идее тут родительский и два дочерних процесса должны бесконечно обмениваться сигналами, но получается, что сначала по сигналу получают 2 дочерних процесса, потом 1(хотя опять же по идее должен 2) сигнал получает родительский процесс, а потом все глохнет. Может быть pause как-то иначе работает при вызове ее в функциях обработки сигналов??
« Последнее редактирование: 20 Апрель 2010, 17:21:34 от miksayer »

Оффлайн Garfeild

  • Активист
  • *
  • Сообщений: 744
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #3 : 20 Апрель 2010, 19:13:35 »
А почему бесконечно-то? Каждый кусок с условиями отработает и завершит свою работу.

Оффлайн _yk

  • Новичок
  • *
  • Сообщений: 13
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #4 : 20 Апрель 2010, 19:40:43 »
>А как по-человечески синхронизировать? :-)
ну хотя бы без sleep'ов)

>Может быть pause как-то иначе работает при вызове ее в функциях обработки сигналов?
все верно - http://linux.die.net/man/2/pause

Оффлайн miksayer

  • Автор темы
  • Любитель
  • *
  • Сообщений: 59
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #5 : 20 Апрель 2010, 20:18:13 »
>А как по-человечески синхронизировать? :-)
ну хотя бы без sleep'ов)
это понятно :-) а что вместо них преминять?
>Может быть pause как-то иначе работает при вызове ее в функциях обработки сигналов?
все верно - http://linux.die.net/man/2/pause
так-с. А как тогда организовать бесконечный обмен сигналами как описано в моем задании?
А почему бесконечно-то? Каждый кусок с условиями отработает и завершит свою работу.
не совсем вас понял. По-моему все должно бесконечно работать.

Оффлайн Garfeild

  • Активист
  • *
  • Сообщений: 744
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #6 : 20 Апрель 2010, 20:21:44 »
не совсем вас понял. По-моему все должно бесконечно работать.
Тогда было бы не плохо объяснить, почему. По моим представлениям,оно не должно работать бесконечно.

Оффлайн miksayer

  • Автор темы
  • Любитель
  • *
  • Сообщений: 59
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #7 : 20 Апрель 2010, 20:28:34 »
не совсем вас понял. По-моему все должно бесконечно работать.
Тогда было бы не плохо объяснить, почему. По моим представлениям,оно не должно работать бесконечно.
тогда опишу по шагам, как я себе представляю алгоритм работы моей программы:
1. Родитель создает 2х сыновей. Они переопределяют свои функции обработки сигнала, а родитель свою.
2. Родитель отправляет сыновьям по сигналу и ждет ответа(через pause).
3. Сыновья получив сигнал выводят сообщение на экран, отправляют ответный сигнал и опять же ждут ответа(через тот же самый pause).
4. Родитель в свою очередь получив сигнал, отправляет сыновьям по сигналу и ждет ответа.
5. и т.д.
Или я чего-то не понимаю?

Оффлайн Garfeild

  • Активист
  • *
  • Сообщений: 744
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #8 : 20 Апрель 2010, 20:38:12 »
Вопрос: почему сыновья должны в очередной раз обработать сигнал с использованием void sighandler(int nsig)?

Оффлайн miksayer

  • Автор темы
  • Любитель
  • *
  • Сообщений: 59
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #9 : 20 Апрель 2010, 20:44:08 »
Вопрос: почему сыновья должны в очередной раз обработать сигнал с использованием void sighandler(int nsig)?
Опаньки! То есть вы хотите сказать, что после каждого принятого сигнала функцию его обработки нужно заново переопределять??

Оффлайн Garfeild

  • Активист
  • *
  • Сообщений: 744
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #10 : 20 Апрель 2010, 20:47:45 »
Именно так.

Оффлайн miksayer

  • Автор темы
  • Любитель
  • *
  • Сообщений: 59
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #11 : 20 Апрель 2010, 20:50:37 »
Спасибо, буду пробовать.

Пользователь решил продолжить мысль 20 Апрель 2010, 22:09:04:
Вот как сейчас выглядит моя программа:
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

pid_t child_1 = 0, child_2 = 0;

void chsigact(int nsig, void (*sa_handlr)(int))
{
  struct sigaction act;
  act.sa_handler = sa_handlr;
  sigaction(nsig, &act, 0);
}

void chsigactinfo(int nsig, void (*sa_sigact)(int, siginfo_t *, void *))
{
  struct sigaction act;
  act.sa_flags = SA_SIGINFO;
  act.sa_sigaction = sa_sigact;
  sigaction(nsig, &act, 0);
}

void sighandler(int nsig)
{
  struct sigaction act;
  printf("child\n");
  //chsigact(SIGUSR1, sighandler);
  act.sa_handler = sighandler;
  sigaction(SIGUSR1, &act, 0);
 
  kill(getppid(), SIGUSR2);
 
  pause();
}

void psighandler(int nsig, siginfo_t * si, void * b)
{
  struct sigaction act;
  printf("pid: %d 1: %d 2: %d\n", si->si_pid, child_1, child_2);
  //chsigactinfo(SIGUSR2, psighandler);
  act.sa_flags = SA_SIGINFO;
  act.sa_sigaction = psighandler;
  sigaction(SIGUSR2, &act, 0);
 
  sleep(1);
  kill(si->si_pid, SIGUSR1);
  //kill(child_2, SIGUSR1);
  //kill(child_1, SIGUSR1);
  pause(); 
}

int main()
{
 
  child_1 = fork();
  if (child_1 == 0)
  {
    struct sigaction act;
    act.sa_handler = sighandler;
    sigaction(SIGUSR1, &act, 0);
   // chsigact(SIGUSR1, sighandler);
    pause();
  }
  else if (child_1 > 0)
  {
    child_2 = fork();
    if (child_2 == 0)
    {
      //chsigact(SIGUSR1, sighandler);
      struct sigaction act;
      act.sa_handler = sighandler;
      sigaction(SIGUSR1, &act, 0);
      pause();
    }
  }
 
  if (child_1 > 0 &&  child_2 > 0)
  {
    //chsigactinfo(SIGUSR2, psighandler);
    struct sigaction act;
    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = psighandler;
    sigaction(SIGUSR2, &act, 0);   

    sleep(1);
    kill(child_2, SIGUSR1);
    kill(child_1, SIGUSR1);
    pause();
  }
  return 0;
}
Все по-старому: выводится 2 сообщения от детей и 1 от родителя. Заметил очень странную вещь: когда я использовал функции, написанные мной для переопределения функций обработки сигналов(их вызовы закомментированы), программа "висла" после этих сообщений и не завершалась даже по Ctrl+C, а теперешний вариант(его отличие состоит только в том, что не происходит вызова функций) завершается по Ctrl+C нормально. Чем может быть обусловлено такое поведение? И почему моя программа и теперь не хочет бесконечно обмениваться сигналами?
« Последнее редактирование: 20 Апрель 2010, 22:09:04 от miksayer »

Оффлайн Garfeild

  • Активист
  • *
  • Сообщений: 744
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #12 : 20 Апрель 2010, 23:04:37 »
Самый главный вопрос, как очередность сигналов все же должна быть?

Пользователь решил продолжить мысль 20 Апрель 2010, 23:08:17:
И еще, рекомендую больше вывода и более информативного сделать)
« Последнее редактирование: 20 Апрель 2010, 23:08:17 от Garfeild »

Оффлайн miksayer

  • Автор темы
  • Любитель
  • *
  • Сообщений: 59
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #13 : 20 Апрель 2010, 23:09:56 »
Вот копия куска задания из методы:
Цитировать
“Отец” одновременно, посылает сигнал SIGUSR1 “сыновьям”. “Сыновья”
получив данный сигнал, посылают в ответ “Отцу” сигнал SIGUSR2. “Отец”
получив сигнал SIGUSR2, через время t=100 мсек одновременно, посылает
сигнал SIGUSR1 “сыновьям”. И так далее... Написать функции-обработчики
сигналов, которые при получении сигнала выводят сообщение о получении
сигнала на экран.
Т.е. отец посылает сигналы сыновьям, а сыновья отцу, все по очереди.

Пользователь решил продолжить мысль 20 Апрель 2010, 21:11:45:
И еще, рекомендую больше вывода и более информативного сделать)
А что там еще можно добавить?
« Последнее редактирование: 20 Апрель 2010, 23:12:48 от miksayer »

Оффлайн Garfeild

  • Активист
  • *
  • Сообщений: 744
    • Просмотр профиля
Re: Проблема с сигналами
« Ответ #14 : 20 Апрель 2010, 23:12:12 »
Я думаю все же стоит как-то поменять синхронизацию.

 

Страница сгенерирована за 0.061 секунд. Запросов: 24.