Question

Je programme un module de communication interprocessus (processus A et processus B).

Existe-t-il un moyen quelconque pour que le fil de communication dans B puisse fonctionner (soit être déverrouillé) dès que le processus A termine une action spécifique, je veux dire sans que B n’effectue une interrogation ni que B attende trop après que A ait terminé son action?

Quels sont les concepts / modèles / modèles de conception régissant ces problèmes? (Quelque chose de plus précis que la synchronisation interprocessus). Quelles bibliothèques / méthodes recommandez-vous?

Merci.

Éditer: je recherche des méthodes adaptées à chacun des trois principaux systèmes d’exploitation: Ms Windows, Apple Mac OS X, GNU / Linux.

Était-ce utile?

La solution

C'est un travail assez difficile:

Pour les systèmes d'exploitation Unix, vous pouvez utiliser:

  • condition pthread et mutex avec l'argument setpshared.

    Remarque: il est bien pris en charge sous Linux 2.6, Solaris, mais il ne prend pas en charge FreeBSD et Cygwin (je ne connais pas Mac OS X)

  • Pour les systèmes Unix, vous pouvez également utiliser des sémaphores nommés, mais je ne connais pas leur niveau de support

  • Pour Windows, il existe des événements ...

C'est un travail difficile, surtout pour IPC ...

Donc si vous voulez quelque chose de portable, je vous suggère de jeter un coup d'oeil sur Boost.Interprocess qui a des conditions et des mutexes ...

Mais assurez-vous que toutes les fonctionnalités sont prises en charge sur tous les systèmes d'exploitation que vous souhaitez prendre en charge.

Éléments à noter à propos de Boost.Interprocess

Vérifiez soigneusement le niveau de prise en charge de chaque système d'exploitation Unix avec lequel vous devez travailler, car Boost.Interprosess utilise des fonctions pthread_ * qui ne sont pas toujours prises en charge ... puis échoue à nouveau pour émulation - vérifiez la qualité de cette émulation

Vérifiez également comment cela fonctionne sous Windows - pour autant que je sache, il n'y a pas de "mémoire partagée". mutex dans l'API Win32, les objets généralement nommés doivent être utilisés, alors vérifiez ce qui est supporté et comment.

Autres conseils

MODIFIER: J'ai pensé à tort que vous deviez synchroniser les threads, Révisé pour IPC

.

Je pense que vous avez besoin de quelque chose comme des événements attendus.

Sous Windows, vous pouvez utiliser CreateEvent ( ) , pour créer (ou obtenir un événement existant) nommé, à réinitialisation automatique.

Lorsque le processus A termine le traitement, il doit appeler < code> SetEvent () , alors que le processus B doit appeler WaitForSingleObject () en veille jusqu'à la fin (ou expiration du délai).

Vous pouvez également utiliser des sémaphores créés par CreateSemaphore () , initialisé à 0. Le processus A signale l’achèvement en appelant ReleaseSemaphore () , alors que le processus B utilise à nouveau WaitForSingleObject () à attendre d'être terminé.

Sous Linux et OS X, vous pouvez utiliser des sémaphores pour obtenir un effet similaire. utilisez sem_open () pour créer un sémaphore nommé, avec 0 comme valeur initiale.

Lorsque le processus A est terminé, il doit appeler sem_post () pour incrémenter le sémaphore, alors que le processus B doit appeler sem_wait () en veille jusqu'à la fin.

REMARQUE : la méthode du sémaphore peut permettre de signaler plusieurs achèvements. Vous devez le gérer en définissant un nombre maximal sous Windows ou en vérifiant l'intégrité de la valeur sem actuelle avec sem_getvalue () p>

Je pense que les variables de condition correspondent à ce que vous essayez de faire, voici un exemple qui fonctionnerait sous Linux et OSX

#include <pthread.h>
/* no error checking, quick and dirty sample */
pthread_mutex_t g_mutex;
pthread_cond_t g_cond;
int a_done = 0;

void init(void)
{
    pthread_mutex_init(&g_mutex, NULL);
    pthread_cond_init(&g_cond, NULL);
}

void thread_a(void *arg)
{
    /* do something here... */
    pthread_mutex_lock(&g_mutex);
    a_done = 1;
    pthread_cond_signal(&g_cond);
    pthread_mutex_unlock(&g_mutex);
}

void thread_b(void *arg)
{
    /* wait for a to complete */
    pthread_mutex_lock(&g_mutex);
    while (!a_done)
        pthread_cond_wait(&g_cond, &g_mutex);
    a_done = 0;
    pthread_mutex_unlock(&g_mutex);
}

Sous Windows, vous pouvez utiliser pthreads-win32 ou des variables de condition natives sous Vista, voir la Variables de condition MSDN pour plus d'informations.

Références:

Si votre système d'exploitation prend en charge les signaux, vous pouvez déverrouiller un mutex depuis un gestionnaire de signaux et envoyer le signal du processus A dès que vous avez terminé la tâche.

Le processus B attendrait un mutex ou un autre outil de synchronisation et A travaillerait sur quoi que ce soit, puis à la fin de l'envoi du signal USR1 par exemple, et le gestionnaire USR1 du processus B déverrouille l'outil de synchronisation correspondant.

Le plus courant consiste à utiliser select () / poll (). Les deux peuvent vérifier plusieurs descripteurs de fichier s'il y a des entrées disponibles. Les deux reçoivent un paramètre de délai d'attente - cela évitera l'attente, qui peut consommer 100% de la CPU. C’est une solution très appropriée pour les applications petites / moyennes.

Une autre approche consiste à effectuer une interrogation dans un thread séparé.

Si vous envisagez de développer une grosse application, cela vaut la peine de se tourner vers ACE cadre ou boost . Ces frameworks sont des solutions multi-plateformes, bien conçues et testées.

Eh bien, à mon avis et selon mon expérience, la meilleure façon de le faire de manière simple et portable consiste à utiliser des prises de courant. De plus, vous avez la possibilité d’avoir les deux processus sur une machine différente (si nécessaire). De plus, vous pouvez étendre la communication pour gérer plus que la synchronisation.

Si vous ne souhaitez pas interroger, utilisez un fil qui attend un message de synchronisation sur un socket. Vous lisez le socket de manière bloquante. Lorsque vous recevez le message, vous utilisez une synchronisation multithread standard pour gérer votre synchronisation. Dans votre cas, comme B devrait attendre la fin de A, il vous suffit de lire de manière bloquante dans votre processus.

Pour être portable, utilisez une bibliothèque de sockets portable telle que boost ou ptypes ou autre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top