int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
С под Linux: Сигналы
Есть дерево процессов такого вида:
...................проц1
..........проц2.........проц3
.....проц5..................проц4
проц6
процесс 1 , шлет сигнал SIGUSR1 - процессам 4,5,6
процессы 4,5,6 - шлют сигналы SIGUSR2 процессам 2 и 3
процессы 2 и 3 - соответственно, 1му процессу SIGUSR1.
Все выводят сообщение после отправки сообщения и получения сообщения, вида "процесс такой-то с pid таким-то, ppid таким-то получил\послал сигнал тому-то(от того-то) в такое-то время " Время задержки на отпривку сигнала 100 мс.
Собственно затруднение вызывает пересылка сигналов от процесса 1 к 4.5.6, от 5 и 6го к 3му и от 4го к 2. Читала что тут можно использовать семафоры, но вот как не понятно. Может можно как-то без них обойтись? Может их можно организовать как-то?
И поясните пожалуйсто попроще. Или помогите с кодом, хоть примерно.
Буду рада, если поможете. Зарание благодарна.
Цитата:
Читала что тут можно использовать семафоры
Семафоры это механизмы блокировки, и тут я тоже не представляю как их использовать.
Из сигналов могу посоветовать посмотреть в сторону системного вызова
Код:
и
Код:
int sigqueue(pid_t pid,
int pidno,
const union sigval value);
int pidno,
const union sigval value);
для отправки сигналов с полезной нагрузкой.
Чуть позже, если будет время, попробую набросать код.
Цитата:
...
для отправки сигналов с полезной нагрузкой.
...
Код:
int sigqueue(pid_t pid,
int pidno,
const union sigval value);
int pidno,
const union sigval value);
для отправки сигналов с полезной нагрузкой.
...
А можно пояснить, что передается в "const union sigval value" в моем случае? 0?
Спасибо.
Для хранения значений всех pid'ов нужно использовать разделяемую память, как я понимаю.
Т.е. первый процесс создает массив из 6 pid'ов, заполняет его нулями и делает его доступным для других процессов. Затем создаются процессы, каждый процесс записывает свое значение pid'а в этот массив и регистрирует обработчик сигнала SIGUSR1. А главный процесс ждет до тех пор пока значения pid'ов для процессов 4, 5 и 6 не станет отличным от 0 и выполняет какой-нибудь такой цикл:
Код:
while(!pid[3] || !pid[4] || !pid[5])
sleep(1);
sleep(1);
после этого посылает им сигналы.
Обработчик сигнала может быть один на всех, а определять какой процесс сейчас выполняется через getpid() и сравнивая его со значениями в массиве. А процесс, отправивший сигнал можно определить из элемента si_pid структуры sigaction в обработчике сигнала.
Код, я думаю, смогу написать не раньше завтрашнего вечера.
Буду ждать, а то у меня никаких идей. Дерево создается, работет, а вот пересылку не могу понять, как организовать этот злополучный массив. И не понятно, как родитель сделает массив доступным?
Прошу прощения что задержался с кодом, были трудности на работе.
Я решил отказаться от разделяемой памяти в пользу анонимных отображений.
Главный процесс создает отображение в памяти доступное для всех остальных процессов с помощью системного вызова mmap().
Каждый процесс записывает значение своего pid'а в этот массив.
Ну собственно рабочий код во вложенном файле. По возможности все старался комментировать.
В данной реализации есть недостатки - каждый процесс выполняется бесконечно. Т.е. после приема/отправки всех сигналов выполнение всех шести процессов продолжается. Убивается только через CTRL+C. Вам необходимо чтобы все процессы завершались после того как выполнили "свою работу"? В таком случае придется городить всякие блокировки, семафоры, глобальные переменные...