Comment coordonner la mémoire partagée entre 2 processus

J’ai le programme A et le programme B. Le programme A crée une queue qui est stockée dans la mémoire partagée avec shmget, puis shmat. Le processus B démarre et utilise ensuite le même shmid pour obtenir la queue créée par le processus A sans problème. Le processus A (évidemment, A et B s’exécutent simultanément) exécute ensuite une méthode qui modifie un certain élément de la queue. Lorsque le programme A fait cela, le pointeur sur ce bloc de mémoire me donne une erreur de segmentation. probablement parce que le programme B a maintenant le pointeur qui le pointe, je suppose. Ma question est la suivante: comment puis-je résoudre ce problème pour que le programme A puisse éditer et lire à partir de la queue, ainsi que le programme B. Je sais que j’ai besoin d’une sorte de verrou, mais je ne sais pas quel type de verrou serait le meilleur ou comment le mettre en œuvre correctement ce. Si vous pouvez mettre en place un exemple de code pour accompagner votre explication, cela aiderait beaucoup. J’écris tout cela en C en passant et le processus A a 2 clés, une pour la queue et l’autre pour un tableau contenant tous les shmids pour chaque segment alloué en mémoire partagée du programme A pour être utilisé par le programme B pour récupérer cette information.

Je suis d’accord avec le commentaire selon lequel il pourrait y avoir de meilleurs moyens de résoudre le problème sous-jacent, par exemple avec des tuyaux. Cependant, comme j’ai un code de test qui fait exactement ce que vous décrivez, je le partagerai avec vous. Notez que lorsque vous exécutez ce code, vous devez toujours démarrer le serveur avant de démarrer le client.

Le code crée une paire de sémaphores en plus de la mémoire partagée. Le client utilise REQUEST_SEM pour signaler au serveur que les données sont disponibles. RESPONSE_SEM est utilisé par le serveur pour indiquer que cela est fait avec la demande du client.

Si vous décidez de modifier la taille de la mémoire partagée, vous devrez utiliser la commande ipcrm pour supprimer la mémoire partagée allouée précédemment. Une autre commande utile est ipcs , qui répertorie les objects IPC que vous avez créés.

Une dernière note. L’utilisation d’une key codée en dur est mauvaise. Consultez la documentation de ftok pour une meilleure façon de générer une key .

Serveur.c

 #include  #include  #include  #include  #include  #include  #include  #define REQUEST_SEM 0 #define RESPONSE_SEM 1 #define SEM_RA (SEM_R | SEM_A) #define SEM_FLAGS (SEM_RA | (SEM_RA >> 3) | (SEM_RA >> 6)) #define MEM_RW (SHM_R | SHM_W) #define MEM_FLAGS (MEM_RW | (MEM_RW >> 3) | (MEM_RW >> 6)) static void error( const char *msg ) { perror( msg ); exit( 1 ); } void waitForIt( int semid, int semnum ) { struct sembuf operations = { semnum, -1, 0 }; if ( semop( semid, &operations, 1 ) < 0 ) error( __func__ ); } void signalIt( int semid, int semnum ) { struct sembuf operations = { semnum, 1, 0 }; if ( semop( semid, &operations, 1 ) < 0 ) error( __func__ ); } int main( int argc, char *argv[] ) { int i, semID, memID, good, bad; char *memAddress; if ( (semID = semget( 0x1001, 2, IPC_CREAT | SEM_FLAGS )) < 0 ) error( "Unable to create semaphores" ); if ( semctl( semID, REQUEST_SEM, SETVAL, 0 ) < 0 ) error( "Unable to initialize request semaphore" ); if ( semctl( semID, RESPONSE_SEM, SETVAL, 0 ) < 0 ) error( "Unable to initialize response semaphore" ); if ( (memID = shmget( 0x1001, 1024, IPC_CREAT | MEM_FLAGS )) < 0 ) error( "Unable to create shared memory" ); memAddress = shmat( memID, NULL, 0 ); if ( memAddress == NULL || memAddress == ((void *) -1) ) error( "Unable to attach shared memory" ); good = 0; bad = 0; for ( i = 0; i < 100; i++ ) { waitForIt( semID, REQUEST_SEM ); if ( memAddress[0] == i ) good++; else bad++; memAddress[0] = 0x55; signalIt( semID, RESPONSE_SEM ); } printf( "good=%d bad=%d\n", good, bad ); if ( shmdt( memAddress ) < 0 ) error( "Unable to detach shared memory" ); } 

Client.c

 #include  #include  #include  #include  #include  #include  #include  #define REQUEST_SEM 0 #define RESPONSE_SEM 1 static void error( const char *msg ) { perror( msg ); exit( 1 ); } void waitForIt( int semid, int semnum ) { struct sembuf operations = { semnum, -1, 0 }; if ( semop( semid, &operations, 1 ) < 0 ) error( __func__ ); } void signalIt( int semid, int semnum ) { struct sembuf operations = { semnum, 1, 0 }; if ( semop( semid, &operations, 1 ) < 0 ) error( __func__ ); } int main( void ) { int i, semID, memID, good, bad; char *memAddress; if ( (semID = semget( 0x1001, 0, 0 )) < 0 ) error( "Unable to get semaphores" ); if ( (memID = shmget( 0x1001, 0, 0 )) < 0 ) error( "Unable to create shared memory" ); memAddress = shmat( memID, NULL, 0 ); if ( memAddress == NULL || memAddress == ((void *) -1) ) error( "Unable to attach shared memory" ); good = 0; bad = 0; for ( i = 0; i < 100; i++ ) { memAddress[0] = i; signalIt( semID, REQUEST_SEM ); waitForIt( semID, RESPONSE_SEM ); if ( memAddress[0] == 0x55 ) good++; else bad++; } printf( "good=%d bad=%d\n", good, bad ); if ( shmdt( memAddress ) < 0 ) error( "Unable to detach shared memory" ); }