Skocz do zawartości
azedor

Zarządzanie Procesami

Rekomendowane odpowiedzi

Witam, mam do napisania w C pod Unixem taki program: Proces macierzysty tworzy 3 procesy (P1, P2, P3) potemne i po ich utworzeniu proces macierzysty ma się zakończyć. Następnie proces P1 ma odczytywać z pliku dane, P2 ma je jakoś zakodować a P3 ma zakodowane informacje wypisać na ekranie. Działanie procesów ma być zsynchronizowane za pomocą semaforów, tzn mają się wykonywać w takiej kolejności P1, P2, P3. I to jest jedna częsc zadania która działą mi bez problemu. Druga częsc tego zadania polegać ma na tym, żę do dowolnegoz tych procesów moge wysłać jeden z trzech sygnałów, tzn sygnał zatrzymania, wznowienia i zabicia procesu(SIGINT, SIGCONT, SIGQUIT), tylko że wysłanie któegoś sygnału do któregoś z trójki procesów powoduje że na ten sygnał mają zareagować wsztystkie 3 procesy. Ma to działać w ten sposób żę w momencie wysłania sygnału np SIGINT do P1 proces P1 proces który otrzymał ten sygnał ma stworzyć łacze komunikacyjne między procesami P1, P2 i P3 i prezz to łącze ma przekazać informacje jakiego działania zarządał użytkownik, np że cche aby procesy zostały wstrzymane. Ja to w ten sposób robie, że Proces który otrzeymał od użytkownika jakiś sygnał otwiera 3 łącza nazwane (pliki), i do każdego łacza zapisuje liczbe która oznacza nr sygnału jaki mają na sobie wykonać poszczegołne procesy za pomocą funkcje raise(int nr_sygn). W momencie gdy dany proces zapisze ten nr sygnbału na wszystkei 3 łącze ma wysłać sygnał do pozostalych procesów (np SIGUSR1) informujacy że powinny odczytać z łącza nr sygnału jaki mają an sobie wykonać. Czyli np z drugiej otwartej konsoli wykonuje kill -SIGINT PID_P1 następnie P1 otwierza 3 łacza, L1, L2 L3, do każdeo z nich zapisuje liczbe 18 potem wysyłą sygnał SIGUSR1 za pomocą funkcje kill(0,SIGUSR2), sygnał ten przechytują wszstkie 3 procesy, łacze z tym ktory go wysłal i w reakcji na niego wywują funkcje która otwiera łacze, w przypadku P1 łącze L1 itd. następnie po odczytaniu z lacze liczby wykonują funkcje raise(nr_sygnał_odczytanego) , funkcja raise(int nr_syg) powoduje wysłanie określonego sygnału do samego siebie.

Teraz tak, ta 2 cześć programu prawie działa mi dobrze, tzn jeśli wyśle sygnał zatrzmania do dowolnego procesu powoduje to zatrzymanie wszystkich trzeach procesów, czyli tworzą się poprawie wszystkie 3 łacza i każdy proces odczytuje poprawnie nr sygnału jaki ma an sobie wykonać, podobnie jest gdy wysyłam zakończenia procesó, również każdy proces odczytuje poprawnie nr sygnału i "zabijają sie". Tylko jest taki problem. W przypadku gdy mam wstrzymane wszystkie procesy, to po wsyłąniu np sygnału zakończenia albo wznowienia te procesy nie reagują wogole.

 

Żeby było jaśnie o co mi chodzi przedstawiam fragment programu, kazdy proces jak widać ma 4 funkcje signal, w sumie każdy proces mozę dostać 4 rózne sygnały(3 sygnały użytkownika i jeeden sygnał pochodzący od ktregoś z procesów) i na każdy muszą zareagować

 

funkcje f1, f2 i f3 są paktycznei identyczne, różnią się tylko tym że inny numer jest zapisywany do łącz nazwanchm, f1 zapisuje 19(sygnał wstrzyamnia) f2 18, f3 9.

 

Funkcje P1, P2, P3 również sąniemal identyczne, różnia się tylko nazwą łącza z którego odczytuja, bo kazdy proces ma osobne łacze.

 

void f1()

{

sig_num=19;

mkfifo("plik",0777); //utworzenie łącz i zapisanie do nich nr sygnału

file=open("plik",0_RDWR);

write(file,&sig_num,4);

mkfifo("plik2,0777);

file2=open("plik2",0_RDWR);

write(file2,&sig_num,4);

mkfifo("plik3",0777);

file3=open("plik3",0_RDWR);

write(file3,&sig_num,4);

 

kill(0,SIGUSR2); //wysłanie sygnału do wszystkich procesów aby odczytały informacje z łącza

}

 

void P1()

{

file=open("plik",O_RDONLY); //odczyt liczby z łącza

read(file,&nd,4);

unlink("plik");

raise(nd); //wysłanie sygnału i nr jaki odczytano

}

 

 

if((fork1=fork())==0)

for(;;)

{

opusc(0,sem_id);

fgetc(buf,80,s);

printf("Wczytano: %s",buf);

strcpy(p,buf);

sleep(1);

signal(SIGINT,f1);

signal(SIGCONT,f2);

signal(SIGQUIT,f3);

signal(SIGUSR2,P1);

podnies(1,sem_id);

}

fclose(plik);

}

else

{

if((fork2=fork())==0)

for(;;)

{

opusc(1,sem_id);

koduj(p);

sleep(1);

signal(SIGINT,f1);

signal(SIGCONT,f2);

signal(SIGQUIT,f3);

signal(SIGUSR2,P3);

podnies(2,sem_id);

}

else

{

if((fork3=fork())==0)

for(;;)

{

opusc(2,sem_id);

printf("Zakodowano: %s\n",p);

sleep(1);

signal(SIGINT,f1);

signal(SIGCONT,f2);

signal(SIGQUIT,f3);

signal(SIGUSR2,P3);

podnies(0,sem_id);

}

}

 

Problem jak już powiedzialm jest w tym że jeśli wstrzymam wszystkie sygnały w wyśle do nich sygnał np wznowienia (SIGCONT) to poporstu nie ma żadnej reakcji, a powina być w końcu każdy sygnał ma funkcje która zostaje wywołana po przechwyceniu sygnału . TO wygląda tak ajkby sygnal wstrzymany wogole nie mógł zareagować na żaden sygnał

tzn jesli wyśle kill -18 pid_procesu to ten proces zostanie wznowiony, ale ja musze do niego wysłać jakiś mój sygnał np SIGCONT i wznowione mają zostać wszystkie 3 procesy.

 

Jęsli ktoś mi podpowie w jaki sposób rozwiazać mój problem to będe bardzo wdzięczny ;)

Cyzli chodzi tylko o to jak zrobić żeby wsstrzymane sygnały zareagowały na sygnał użytkownika i fykonały określoną funkcje. Albo w jaki sposób sprawić że mam wstrzymane te 3 sygnały i chce wysyłajac do jednego z sygnał wznowienia wznowić wszystkie ?

Podkreślam jescze raz że wszystko działa dobrze prócz wysylania sygnału do wstrzymanego procesu.

 

 

Zmienie może moje pytanie bo nie każdemu się mozę chcieć przeczytać co tam napisalem :D

 

Czy wstrzymany proces możę przechwytywać sygnału użytkownika ?

Bo ja zrobioem sobie prosty programik, dalem w nieskończnej pętli żeby mie wypisywał jakiś tekst, następnie zatrzymałęm ten program i wsyłalem do niego sygnał SIGUSR1 i w programie miałem funkcje signal(SIGUSR1, f), która po przechwyceniu sygnału miała mi wywołac funkcje f, ale jej nie wywylała, tak jakby poprostu wstrzymany proces nie byl w stanie przechwytywać sygnalów użtykownika

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...