Problem bei Prozesssynchronisation mit POSIX-Semaphoren unter SUSE 8.1
-
Ich schreibe ein Programm, dass zwei Prozesse unter Linux startet. Diese enthalten kritische Bereiche, die gegeneinander abgesichert sein sollen.
Dazu erstelle ich einen Semaphor mit
semid = semget(IPC_PRIVATE, 1, IPC_CREAT|0777);
Dann bereite ich die Semaphor-Operationen vor:
sem_p[0].sem_num = 0; sem_v[0].sem_num = 0; sem_p[0].sem_op = 1; sem_v[0].sem_op = -1;
Danach erstelle ich mit fork() zwei Kindprozesse. Diese müssten dann ja die Semaphoren enthalten.
Nun möchte ich die kritischen Bereiche in den Kindprozessen absichern:
kindprozess() { semop(semid, sem_p, 1); //Kritischer Bereich semop(semid, sem_v, 1); }
Aber die kritischen Bereiche der beiden Kindprozesse überlagern sich trotzdem. Wo liegt mein Fehler?
-
Uh, ich hab lange nichts mehr mit Semaphoren gemacht, aber den Beispiel Code hab ich noch rumfliegen, vielleicht hilft er dir
#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/stat.h> #include <sys/wait.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int id; struct sembuf semaphor; void critical() { printf("CRITICAL %d\n",getpid()); } void lock() { semaphor.sem_op=-1; semaphor.sem_num=0; semaphor.sem_flg=SEM_UNDO; if(semop(id,&semaphor,1)==-1) { perror("semop"); exit(1); } } void unlock() { semaphor.sem_op=1; semaphor.sem_num=0; semaphor.sem_flg=SEM_UNDO; if(semop(id,&semaphor,1)==-1) { perror("semop"); exit(1); } } void child() { for(;;) { lock(); critical(); unlock(); } } pid_t make_child() { pid_t pid=fork(); if(pid==-1) { perror("fork"); exit(1); } else if(!pid) child(); else return pid; return 0; } int main() { id=semget(IPC_PRIVATE,1,IPC_CREAT|IPC_EXCL |S_IRWXU|S_IRWXG|S_IRWXO); if(id==-1) { perror("semget"); return 1; } semctl(id,0,SETALL); make_child(); make_child(); int status; wait(&status); wait(&status); return 0; }
-
Erstmal Danke für die schnelle Antwort.
Aber es funktioniert nicht. Zuerst habe ich deine Variante in meinen Code eingebaut ... das ging nicht. Dann habe ich dein komplettes Beispiel 1:1 übernommen und das funktioniert auch nicht. Es kommt gar keine Ausgabe.
Ich habe in die lock()-Methode eine printf()-Ausgabe eingebaut. Diese zeigt, dass beide Prozesse in die Methode lock() gehen. Aber nach semop(id, &semaphor, 1) rührt sich gar nichts mehr.
Könnte das vielleicht mit meinem SuSe 8.1 zusammenhängen?
-
Ich habe jetzt herausgefunden warum dein Beispielcode nicht funktioniert. Wenn man ein Semaphorenset anlegt, dann werden die Semaphoren darin standardmäßig mit 0 (also belegt) initialisiert. Also muss man nach semget schon eine erste Operation, die den Semaphor hochzählt, ausführen.