POSIX Shared Memory
Verfasst: Sa Apr 15, 2017 7:32 pm
Ich experimentiere gerade ein wenig mit Shared Memory und bin dabei aber auf ein Problem gestoßen, auf dessen Lösung ich bisher einfach nicht komme. Ich habe auch schon einiges ausprobiert aber zunächst einmal zu meinem Problem:
Ich habe jetzt einen POSIX Shared Memory eingerichtet, um Daten zwischen Prozessen auszutauschen, da ich ein paar Prozesse starte und die dann mit einem exec Aufruf ein seperates Programm ausführen und das ja auch sonst so nicht möglich wäre. In meinem Programm, dass die ganzen Prozesse startet lege ich den Shared Memory an. Dann blende ich den SHM in de aktuellen Prozess ein und speichere darin eine Struktur, in der dann auch die Anzahl der gestarteten Prozesse steht und weitere Infos.
Dann werden die neuen Prozesse mit fork erzeugt aber jetzt kommt mein Problem. Ich würde dann natürlich auch gerne die PID der neuen Prozesse noch im SHM abspeichern. Kann ich denn dann nachher noch an der Stelle in der Struct die Werte manipulieren? In der Struct my_env_t verwende ich nämlich wieder eine Struct, die sich my_proc_t nennt aber leider funktioniert das so gar nicht.
Hier mal ein wenig Code:
Hier einmal ein Ausschnitt der Strukturen
Das was ich auskommentiert habe, also über dem execvp Aufruf funktioniert nämlich so leider nicht. Dann steht nämlich an jedem index des procs Array 0 und nicht der gewünschte pid Wert. Wenn ich einfach vor dem execvp bzw. vor dem if Block
mache, dann wird das ja von jedem Prozess aufgerufen und die pids in dem procs Array stimmen dann auch nicht mehr oder jeweils nur ein Wert. Wie kriege ich das also hin, dass ich nachher in meinem procs Array die richtigen pids habe?
Aus dem anderen Programm (oder den Prozessen) nachher auf den SHM zuzugreifen oder die Struct my_env funktioniert soweit schon einmal. Da habe ich dann auch den richtigen SHM Namen drinstehen und auch die richtige Anzahl (num_of_procs) drinstehen aber das mit dem procs Array funktioniert nicht richtig. Wie kann ich da also vorgehen?
Das mit der Adressarithmetik funktioniert wie gesagt leider auch nicht, wo ich die Zeilen ptr += habe. Dann steht überall 0 und nicht eine einzige richtige pid. Geht das so mit der struct in der struct nicht und sollte ich das seperieren oder mache ich da bei der Arithmetik was falsch oder gibt es da einen anderen Weg? Ich brauche nämlich die pid's aller gestarteten Prozesse ...
Ich habe jetzt einen POSIX Shared Memory eingerichtet, um Daten zwischen Prozessen auszutauschen, da ich ein paar Prozesse starte und die dann mit einem exec Aufruf ein seperates Programm ausführen und das ja auch sonst so nicht möglich wäre. In meinem Programm, dass die ganzen Prozesse startet lege ich den Shared Memory an. Dann blende ich den SHM in de aktuellen Prozess ein und speichere darin eine Struktur, in der dann auch die Anzahl der gestarteten Prozesse steht und weitere Infos.
Dann werden die neuen Prozesse mit fork erzeugt aber jetzt kommt mein Problem. Ich würde dann natürlich auch gerne die PID der neuen Prozesse noch im SHM abspeichern. Kann ich denn dann nachher noch an der Stelle in der Struct die Werte manipulieren? In der Struct my_env_t verwende ich nämlich wieder eine Struct, die sich my_proc_t nennt aber leider funktioniert das so gar nicht.
Hier mal ein wenig Code:
Code: Alles auswählen
int i;
int fd;
void *ptr;
pid_t pid;
my_env_t my_env;
// SHM erzeugen und Variablen in my_env speichern
// ....
/* now map the shared memory segment in the address space of the process */
ptr = mmap(0, sizeof(my_env_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
error_routine("mmap() failed\n");
}
memcpy(ptr, &my_env, sizeof(my_env_t));
char *pass_argv[argc + 1]; // + 1 fuer NULL;
memset(pass_argv, 0, argc);
pass_argv[0] = argv[2];
for(i = 1; i < argc; i++) {
pass_argv[i] = argv[i];
}
pass_argv[argc] = NULL;
for(i = 0; i < num_procs; i++) {
pid = (int) fork();
if(pid < 0) {
error_routine("Fork() error");
}
else if(pid == 0) {
my_env.procs[i].pid = getpid();
break;
}
}
// ptr += sizeof(my_env_t);
// memcpy(ptr - ((sizeof(my_proc_t) * my_env.num_of_procs) + sizeof(my_proc_t) * i), &my_env.procs[i], sizeof(my_proc_t));
memcpy(ptr, &my_env, sizeof(my_env_t)); // Laueft auch so nicht
if(pid == 0) {
if(execvp(argv[2], pass_argv) < 0) {
error_routine(strerror(errno));
}
}
// SHM bereinigen und auf Kinder warten
// ...
Code: Alles auswählen
typedef struct {
int len;
// ...
} my_msg_t;
typedef struct {
pid_t pid;
// ....
my_msg_t msgs[MAX_MESSAGES_PROC];
} my_proc_t;
typedef struct {
char *shm_name;
// ....
int num_of_procs;
// ...
my_proc_t procs[MAX_PROCS];
} my_env_t;
Code: Alles auswählen
memcpy(ptr, &my_env, sizeof(my_env_t));
Aus dem anderen Programm (oder den Prozessen) nachher auf den SHM zuzugreifen oder die Struct my_env funktioniert soweit schon einmal. Da habe ich dann auch den richtigen SHM Namen drinstehen und auch die richtige Anzahl (num_of_procs) drinstehen aber das mit dem procs Array funktioniert nicht richtig. Wie kann ich da also vorgehen?
Das mit der Adressarithmetik funktioniert wie gesagt leider auch nicht, wo ich die Zeilen ptr += habe. Dann steht überall 0 und nicht eine einzige richtige pid. Geht das so mit der struct in der struct nicht und sollte ich das seperieren oder mache ich da bei der Arithmetik was falsch oder gibt es da einen anderen Weg? Ich brauche nämlich die pid's aller gestarteten Prozesse ...