LINUX.ORG.RU

Вопрос по статусу процесса

 , , ,


0

2

Есть родитель и два дочерних процесса от него. Дочерние процессы активно взаимодействуют между собой. Активируют и стопают друг друга при помощи SIGCONT и SIGSTOP. Но изредка иногда возникает ситуация, что один из процессов не успел застопаться, а второй ему уже посылает SIGCONT и в итоге все стопается. Как узнать статус процесса, прежде чем отправлять ему SIGCONT и отправить только в том случае, если он успел заснуть?


очевидно посылать управляющие сигналы из одного источника, а не из многих

quester ★★
()

гуглите «гонка данных» и т.п...

anonymous2 ★★★★★
()

RTFM: смотреть флажки WUNTRACED и WCONTINUED в man waitpid.

Но тут дело не в статусе. Это хрупкий «механизм взаимодействия», т.е. примерно невозможно добиться надежной/стабильной работы.

В небольшом «кусте» процессов порожденных форками одного экзешника лучше организовать небольшой разделяемый кусок памяти, в котором разместить shared-мьютексы, shared-convarы и shared-barriers.

Deleted
()

а второй ему уже посылает SIGCONT и в итоге все стопается

А чего бы всему стопаться, если SIGCONT на не стопнутый процесс ничего не делает и тот продолжает работать?

Как узнать статус процесса

Статус узнать можно, но гонка всё равно останется. Поэтому лучше просто перепиши приложение по-человечески - надёжных средств синхронизации придумано навалом. Объясни зачем тебе эта ерунда с сигналами?

slovazap ★★★★★
()
Ответ на: комментарий от Deleted

В небольшом «кусте» процессов порожденных форками одного экзешника лучше организовать небольшой разделяемый кусок памяти, в котором разместить shared-мьютексы, shared-convarы и shared-barriers.

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

dhelli
() автор топика
Ответ на: комментарий от slovazap

А чего бы всему стопаться, если SIGCONT на не стопнутый процесс ничего не делает и тот продолжает работать?

Код двух дочерних процессов имеет следующий вид:

/* child1 */
for (;;)
{
    raise(SIGSTOP);
    /* TO DO */
    kill(child2, SIGCONT);
}
/* child2 */
for (;;)
{
    raise(SIGSTOP);
    /* TO DO */
    kill(child1, SIGCONT);
}

Откуда видно, что если один из дочерних процессов пошлет другому SIGCONT, пока второй не успеет послать самому себе SIGSTOP, то все зависнет.

dhelli
() автор топика
Ответ на: комментарий от dhelli

Ох. Этот шедевр может занять почётное место в любой коллекции wtf-кода.

slovazap ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.