Les processus enfants copient-ils des tableaux entiers?

J’écris un programme UNIX de base qui implique des processus d’envoi de messages les uns aux autres. Mon idée pour synchroniser les processus est simplement d’avoir un tableau de drapeaux pour indiquer si un processus a atteint ou non un certain point dans le code.

Par exemple, je souhaite que tous les processus attendent leur création. Je veux aussi qu’ils attendent d’avoir fini d’envoyer des messages avant de commencer à lire leurs chansons.

Je suis conscient qu’un processus effectue une opération de copie en écriture lorsqu’il écrit sur une variable précédemment définie.

Ce que je me demande, c’est que si je crée un tableau de drapeaux, le pointeur sur ce tableau sera copié ou le tableau entier sera-t-il copié (rendant ainsi mon idée inutile).

J’aime aussi tous les conseils sur la communication entre processus et la synchronisation des processus.

EDIT: Les processus écrivent dans le processus de chaque processus. Chaque processus enverra les informations suivantes:

typedef struct MessageCDT{ pid_t destination; pid_t source; int num; } Message; 

Donc, juste la source du message et un nombre aléatoire. Ensuite, chaque processus imprimera le message à stdout: Quelque chose du type “processus 20 reçu 5724244 du processus 3”.

Les processus Unix ont des espaces d’adressage indépendants. Cela signifie que la mémoire de l’un est totalement séparée de la mémoire dans une autre. Lorsque vous appelez fork (), vous obtenez une nouvelle copie du processus. Immédiatement après le retour de fork (), la seule différence entre les deux processus est la valeur de retour de fork (). Toutes les données des deux processus sont identiques, mais ce sont des copies. La mise à jour de la mémoire dans l’une ne peut pas être connue par l’autre, à moins que vous ne preniez des mesures pour partager la mémoire.

Il existe de nombreux choix pour la communication interprocessus (IPC) dans Unix, notamment la mémoire partagée, les sémaphores, les tubes (nommés et non nommés), les sockets, les files de messages et les signaux. Si vous Google ces choses, vous trouverez beaucoup à lire.

Dans votre cas particulier, en essayant de faire en sorte que plusieurs processus attendent qu’ils atteignent tous un certain point, je pourrais utiliser un sémaphore ou une mémoire partagée, selon qu’un processus maître les a tous lancés ou non.

S’il existe un processus maître qui lance les autres, le maître peut configurer le sémaphore avec un nombre égal au nombre de processus à synchroniser, puis les lancer. Chaque enfant pourrait alors décrémenter la valeur du sémaphore et attendre que la valeur du sémaphore atteigne zéro.

S’il n’y a pas de processus maître, je pourrais créer un segment de mémoire partagée contenant un nombre de processus et un indicateur pour chaque processus. Mais lorsque vous avez deux processus ou plus utilisant la mémoire partagée, vous avez également besoin d’un mécanisme de locking (probablement un sémaphore) pour vous assurer que deux processus n’essayent pas de mettre à jour la mémoire partagée simultanément.

Gardez à l’esprit que la lecture d’un canal sur lequel personne n’écrit ne bloque le lecteur jusqu’à ce que des données apparaissent. Je ne sais pas ce que font vos processus, mais peut-être que c’est assez de synchronisation? Une autre chose à considérer si vous avez plusieurs processus écrivant sur un canal donné, leurs données peuvent être entrelacées si les écritures sont plus grandes que PIPE_BUF. La valeur et l’emplacement de cette macro dépendent du système.

-Kevin

L’ensemble des drapeaux semble être copié. Il ne sera pas réellement copié tant qu’un processus ou un autre n’y aura pas écrit. Mais c’est un détail d’implémentation et transparent aux processus individuels. En ce qui concerne chaque processus, ils reçoivent chacun une copie du tableau.

Il y a des moyens pour que cela n’arrive pas. Vous pouvez utiliser mmap avec l’option MAP_SHARED pour la mémoire utilisée pour vos indicateurs. Ensuite, chaque sous-processus partagera la même région de mémoire. Il y a aussi la mémoire partagée de Posix (que, je pense, BTW est un hack terrible). Pour en savoir plus sur la mémoire partagée de Posix, consultez la page de shm_overview(7) .

Mais utiliser la mémoire de cette manière n’est pas vraiment une bonne idée. Sur les systèmes multi-core, il arrive parfois que lorsqu’un processus (ou un thread) écrit dans une zone de mémoire partagée, tous les autres processus verront la valeur écrite immédiatement. Fréquemment, la valeur restra en suspens pendant un certain temps dans le cache L2 et ne sera pas immédiatement purgée.

Si vous souhaitez communiquer en utilisant la mémoire partagée, vous devrez utiliser des mutex ou des opérations atomiques C ++ 11 pour vous assurer que les écritures sont correctement vues par les autres processus.