Mise à jour de la mémoire partagée par différents processus

J’écris du code pour un projet et j’ai un problème lorsque j’essaie de mettre à jour une zone de mémoire partagée avec un autre processus. Fondamentalement, un processus crée une mémoire partagée, puis crée un enfant qui, en utilisant execve, exécute un processus dont le but est de mettre à jour cette mémoire partagée en connaissant sa clé. A la fin, le processus principal affiche toutes les données du shm au stdout.

À ce stade, j’ai remarqué que shm n’a pas été mis à jour. Je ne peux pas comprendre pourquoi. J’ai essayé avec une affectation régulière ( = ) ou assigné à chaque champ une fonction ( updatef ), mais cela ne fonctionne pas. (Bien sûr, dans le vrai programme, j’ai utilisé des sémaphores pour réguler l’access au shm, j’ai écrit ce code pour minimiser le code pour voir le problème)

Processus t:

 #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #define mykey 100 #define maxname 100 #define shmsz 5 #define perms 0666 struct pdata{ pid_t ppid; char ptype; char pname[maxname]; unsigned long pgenome; }; void updatef(struct pdata a, struct pdata p){ a.ppid = p.ppid; a.ptype = p.ptype; strcpy(a.pname, p.pname); a.pgenome = p.pgenome; } int main(){ int shmid; struct pdata *addr; shmid = shmget(mykey, sizeof(struct pdata) * shmsz, IPC_CREAT | perms); addr = (struct pdata*) shmat(shmid, NULL, 0); for(int i=0; i<shmsz; i++){ addr[i].ppid = -1; } switch(fork()){ case 0: { char *args[] = {"u", NULL}; execve("u", args, NULL); } break; } sleep(2); for(int i=0; i<shmsz; i++){ printf("%d %c %s %lu\n", addr[i].ppid, addr[i].ptype, addr[i].pname, addr[i].pgenome); } shmdt(addr); shmctl(shmid, IPC_RMID, 0); return 0; } 

Processus u:

 #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #define mykey 100 #define maxname 100 #define shmsz 5 #define perms 0666 struct pdata{ pid_t ppid; char ptype; char pname[maxname]; unsigned long pgenome; }; void updatef(struct pdata a, struct pdata p){ a.ppid = p.ppid; a.ptype = p.ptype; strcpy(a.pname, p.pname); a.pgenome = p.pgenome; } int main(){ int shmid; struct pdata *addr; struct pdata p; shmid = shmget(mykey, sizeof(struct pdata) * shmsz, perms); addr = (struct pdata*) shmat(shmid, NULL, 0); p.ppid = getpid(); p.ptype = 'A'; strncpy(p.pname, "PIPPO", maxname); p.pgenome = 10; for(int i=0; i<shmsz; i++){ updatef(addr[i], p); } shmdt(addr); return 0; } 

La réponse courte est bien sûr de passer le pointeur à la place de la valeur et cela se fera

 updatef(&arr[i], p); 

La longue réponse réside dans pass by value et passe par référence, lorsque updatef est appelé avec addr[i] comme dans

 updatef(arr[i], p); 

essentiellement la valeur est copiée à la fonction appelante et ne se répercute jamais sur le pointeur attaché viz addr à la suite de addr pointeur addr original rest inchangé quand on passe l’adresse comme

 updatef(&addr[i], p); //or updatef(addr+i, p); 

la référence est passée, inturn mettra à jour le contenu pointé par le pointeur addr+i

append sur IMO fractionnement le code rendra cette plus présentable et lisible et maintenable et bla bla bla ici est un peu

Fichier 1 – sh , conservez les données partagées et globales ici

 #ifndef S_H_INCLUDED #define S_H_INCLUDED #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #define mykey 100 #define maxname 100 #define shmsz 5 #define perms 0666 struct pdata{ pid_t ppid; char ptype; char pname[maxname]; unsigned long pgenome; }; #endif 

tc

 #include "sh" // include global header here int main(){ int shmid; struct pdata *addr; shmid = shmget(mykey, sizeof(struct pdata) * shmsz, IPC_CREAT | perms); addr = (struct pdata*) shmat(shmid, NULL, 0); for(int i=0; i 

uc

 #include "sh" // common included here static void updatef(struct pdata *a, struct pdata p){ a->ppid = p.ppid; a->ptype = p.ptype; strcpy(a->pname, p.pname); a->pgenome = p.pgenome; } int main(){ int shmid; struct pdata *addr; struct pdata p; shmid = shmget(mykey, sizeof(struct pdata) * shmsz, perms); addr = (struct pdata*) shmat(shmid, NULL, 0); p.ppid = getpid(); p.ptype = 'A'; strncpy(p.pname, "PIPPO", maxname); p.pgenome = 10; for(int i=0; i 

et l'étape finale de la construction

 gcc tc -ot gcc uc -ou