Synchronisation interprocessus utilisant des signaux en c, linux

Processus Une fourche indique 4 processus enfants. exec () est utilisé pour remplacer le code des enfants. Les enfants s’initialisent et doivent attendre que le parent crée tous les 4 d’eux.

Ensuite, le parent envoie un sigusr1 à chaque processus enfant afin qu’il puisse commencer le traitement. Le parent attend que tous les enfants terminent leur traitement. Lorsqu’un enfant termine son travail, il envoie un sigusr2 au parent. Lorsque le parent reçoit tous les signaux sigusr2, il poursuit l’exécution en fusionnant les calculs des processus enfants.

Il s’agit d’un exercice universitaire et il a été indiqué en classe que le processus A (parent) perdrait certains signaux. Nous avons donc reçu pour instruction de n’exiger qu’un pourcentage des signaux des enfants pour qu’ils soient correctement reçus.

Je voudrais atteindre 100%. Dans l’autre cas, une pause () et une boucle vont-elles fonctionner?

Si vous utilisez la méthode standard signal() , le processus A peut perdre certains signaux si de nombreux enfants lui envoient le même signal très rapidement. Si vous gérez un signal et recevez pendant ce temps le même signal, vous perdrez le second (plus précisément, il sera capturé par le gestionnaire de signal par défaut).

Si vous décidez d’utiliser sigaction() vous pourrez capturer tous les signaux envoyés à votre processus.

D’autres intervenants ont déjà expliqué comment éviter de perdre des signaux. Cela dit, je recommanderais de ne pas utiliser de signaux du tout. Etant donné que les signaux peuvent s’interrompre à tout moment (même lorsque les verrous sont maintenus!), Il est très difficile d’écrire un code de sécurité des signaux plus complexe que, par exemple, l’écriture d’un drapeau dans un fifo ou l’incrémentation d’un événement.

En tant que tel, pourquoi ne pas simplement utiliser un tube ou un eventfd pour signaler son achèvement? Cela garantit non seulement que tous les messages écrits parviendront au processus parent, mais évite également les problèmes de synchronisation en permettant à votre processus de recevoir des données du canal / eventfd uniquement lorsqu’il est prêt.

Vous devez utiliser sigaction() ; Cependant, vous pouvez encore perdre certaines d’entre elles car:

Les signaux ne sont pas en queue. Les processus enfants envoient SIGUSR2 et s’ils se produisent en même temps, un seul d’entre eux sera remis.

Le meilleur moyen est d’utiliser des signaux en temps réel à l’aide de sigqueue() .

Vous utiliserez signal alrm et pause dans le processus parent qui attendra que le processus enfant génère un signal d’alarme qui décompose l’instruction pause et les synchronise. .