C-Programm: Message Queue und Semaphore mit IPC
Programm Schreiber-Cola: Message Queue mit Semaphoren
Das folgende Programm liest Name (maximal 80 Zeichen), Adresse und Gehalt (long integer) eines Mitarbeiters, bis im Feld "Name" das Wort FIN eingegeben wird. Die Informationen werden anschließend in eine Message Queue mit dem Typ der Meldung geschrieben. Während der Ausführung des Programms dürfen andere Verfahren nicht auf die Message Queue zugreifen. Es dürfen höchstens zwei Prozesse gleichzeitig auf die Warteschlange zugreifen, um Nachrichten zu extrahieren.
Datenstruktur
struct Mitarbeiter
long type;char name[80];char dir[80];long gehalt;
Quellcode (korrigiert)
struct Mitarbeiter {
long type;
char name[80];
char dir[80];
long gehalt;
};
int main() {
int semid, colaid, nb;
struct Mitarbeiter empleado;
struct sembuf op;
key_t key;
if ((key = ftok("/", 'A')) == -1) {
perror("Fehler beim Erstellen des Schlüssels");
return 1;
}
if ((semid = semget(key, 2, IPC_CREAT | 0666)) == -1) {
perror("Fehler beim Erstellen der Semaphore");
return 1;
}
if ((colaid = msgget(key, IPC_CREAT | 0666)) == -1) {
perror("Fehler beim Erstellen der Message Queue");
return 1;
}
if (semctl(semid, SESC, SETVAL, 1) == -1 || semctl(semid, SLEC, SETVAL, 0) == -1) {
perror("Fehler beim Initialisieren der Semaphore");
return 1;
}
op.sem_num = SESC;
op.sem_op = -1;
op.sem_flg = 0;
if (semop(semid, &op, 1) == -1) {
perror("Fehler beim Erwerben der Semaphore Schreiber");
}
puts("Namen eingeben");
nb = read(0, empleado.name, sizeof(empleado.name));
empleado.name[nb-1] = '\0';
while (strcmp(empleado.name, "FIN") != 0) {
fflush(stdin);
puts("Art eingeben");
do {
puts("Gib die Art <1,2,3> ein\n");
scanf("%ld", &empleado.type);
} while (empleado.type < 1 || empleado.type > 3);
fflush(stdin);
puts("Adresse eingeben");
nb = read(0, empleado.dir, sizeof(empleado.dir));
empleado.dir[nb-1] = '\0';
fflush(stdin);
puts("Gehalt eingeben");
scanf("%ld", &empleado.gehalt);
if (msgsnd(colaid, &empleado, sizeof(empleado) - sizeof(long), IPC_NOWAIT) == -1) {
perror("Daten konnten nicht an die Warteschlange gesendet werden");
break;
}
printf("Informationen gesendet\n");
puts("Namen eingeben");
nb = read(0, empleado.name, sizeof(empleado.name));
empleado.name[nb-1] = '\0';
}
op.sem_num = SLEC;
op.sem_op = 1;
op.sem_flg = 0;
if (semop(semid, &op, 1) == -1) {
perror("Fehler beim Freigeben der Semaphore Leser");
}
printf("Drücken Sie eine Taste, um die IPCs zu löschen\n");
getchar();
fflush(stdin);
if (semctl(semid, 0, IPC_RMID, 0) == -1) {
perror("Fehler beim Löschen der Semaphore");
}
if (msgctl(colaid, IPC_RMID, 0) == -1) {
perror("Fehler beim Löschen der Warteschlange");
}
return 0;
}