PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Interprozesskommunikation Unix/Linux


Liar
15.07.2007, 15:45
Ich beschäftige mich zur Zeit mit der Interprozesskommunikation (und Syncronisation) unter Unix/Linux und möchte ein "Nachrichtensystem" programmieren.
Das Prinzip is ähnlich wie bei einem chat:
Viele Clients (Prozesse) können nachrichten vom terminal an einen Server schicken, der diese einfach auf dem Bildschirm ausgibt.
Dazu verwende ich ein Shared Memory und eine Semaphore, die den Shared Memory bewacht.


#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <unistd.h>
#include <errno.h>

#define SHM_KEY 12
#define SEM_KEY 5


int main(int argc, char** argv)
{
if (argc != 2) {
printf("Usage: %s 1 = Server, 2 = Client\n", argv[0]);
exit(0);
}
int args = (int) argv[1];
int shm_id = shmget(SHM_KEY, 10000, IPC_CREAT | 0666); // shared memory besorgen
const void* shm_pointer = shmat(shm_id, 0, SHM_RDONLY); // shared memory zuweisen

int sem_id = semget(SEM_KEY, 1, IPC_CREAT | 0666); // Semaphore holen
semctl(sem_id, 0, SETVAL, 1); // Semaphore initialisieren

if (errno) {
fprintf(stderr, "error: %s\n", strerror(errno));
exit(-1);
}

struct sembuf op[1]; // Semaphore operationen
int retval; // return value von semop()

op[0].sem_num = 0; // Semaphore nummer 1
op[0].sem_flg = 0; // Flag auf warten setzen

/* Starten: Mit der Semaphore in den kritischen bereich eintreten und lesen oder schreiben */
while (true)
{
op[0].sem_op = 0; // P Operation
if((retval = semop(sem_id, op, 1)) == 0) // P ausführen
{
if(args == 1) {
printf("%s\n", shm_pointer); // Shared memory lesen
}
else if (args == 2) {
scanf("%s\n", shm_pointer); // Shared memory schreiben
}
else {
printf("wrong parameter, exiting\n");
exit(0);
}
}
else // P Operation Fehlgeschlagen
{
fprintf(stderr, "error: %s\n", strerror(errno));
exit(-1);
}
op[0].sem_op = 1; // V Operation
if((retval = semop(sem_id, op, 1)) != 0) // V ausführen & Fehler abfangen
{
fprintf(stderr, "error: %s\n", strerror(errno));
exit(-1);
}
}
return 0;
}

Parameter 1 = server und 2 = client.
Der Code läuft auch, allerdings liest der Server die Daten nicht aus.
Liegt das am shm_pointer der void* ist (printf/scanf probleme?) oder muss ich eventuell sogar noch signale verwenden?

besten dank im vorraus


Jan Krüger
15.07.2007, 17:40
Es wäre sicher eine gute Idee, ein bisschen Fehlerbehandlung einzubauen. Ansonsten fällt mir auf die Schnelle auf, dass du in beiden Prozessen den Speicherbereich als RDONLY anhängst, also kann keiner der beiden Prozesse darauf schreiben.

TekWarrior
15.07.2007, 23:48
Ich verschiebe das ganze mal ins Unix Forum :).