Это связано с планированием процесса.
Когда вы «отправляете» сигнал, устанавливается соответствующий бит на печатной плате ( Блок управления процессом ).и затем, когда процесс, которому был отправлен сигнал, запланирован, он проверяет сигналы и запускает обработчики.
В вышеприведенном примере родительский процесс отправляет сигналы один за другим, но нет гарантии, что 'son1 'будет выполнен раньше, чем' son2 '.
Sleep просто позволяет операционной системе «переключать контекст», то есть разрешать запуск другой программы.Итак, в этом случае
kill(son1, SIGUSR1);
sleep(1);
kill(son2, SIGUSR2);
Вы отправляете сигнал son1, а затем переводите родительский процесс в спящий режим.Однако не обязательно, чтобы процесс son1 был запланирован перед родительским процессом снова.Это зависит от планировщика процессов операционной системы.Вам нужно будет использовать какой-нибудь мьютексный механизм, например семафоры, если вы хотите добиться синхронизации, как вы упомянули.
Надеюсь, что все прояснится.
Редактировать: Также в Linux обработчики сигналовоставаться зарегистрированным даже после последующих вызовов к ним, в отличие от Unix, где обработчики сигналов становятся незарегистрированными после одного вызова.Это означает, что вы должны вызывать signal () только один раз в своих дочерних программах вместо вызова в каждой итерации ваших циклов while ().