Mam problem z pause(). Są trzy procesy P1 P2 i P3. Używam czterech sygnałów SIGUSR1 SIGUSR2 SIGINT SIGCONT. SIGUSR1 zdefiniwany jako wstrzymanie - procedura wstrzymanie(), SIGUSR2 wyjście ze wstrzymania - procedura wznowienie(), SIGCONT - ten sygnał w moim programie wysyłają pomiędzy sobą procesy. I tak:
- wysyłam SIGUSR1 do któregoś z procesów
- ten proces zapisuje w pliku "ins" ciąg znaków "wstrzymanie"
- następnie wysyła sygnał SIGCONT do dwóch pozostałych procesów aby te otworzyly sobie plik i przeczytały co mają zrobić.
- wykonuje pause();
W rezultacie wszystkie 3 procesy są w stanie pause. I teraz pojawia się problem. Wysyłam sygnał SIGUSR2 do dowolnego procesu czyli chcę wznowić wszystkie. Wznawia się tylko proces do którego wysłałem sygnał. Pozostałe dwa procesy są dalej w pause. Proces do którego wysłałem SIGUSR2 wysyła instrukcjami
while( (fscanf(fp2, "%d\n", &pid)) != EOF){
if( pid != getpid() ) kill(pid, SIGCONT);
}
sygnał SIGCONT do tych dwóch pozostałych. Niestety nie wyświetla się pierwsza instrukcja z procedury czwarty() czyli printf("Test\n"); Procesy te nie reagują na ten sygnał gdy są w pause(). Jak mam to zmienić tak aby wszystko działało?
Dzięki za pomoc.
Ponieżej wklejam spreparowany kod mojego programu (jedyne zadanie procesów to while(1) bo nie w tym problem co one robią :) )
#include<stdio.h>
#include<signal.h>
#include<errno.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/msg.h>
#include "pv.h"
#define MAXOBN 50
FILE *fp, *fp2;
void wstrzymanie();
void wznowienie();
void zakonczenie();
void czwarty();
int semid2;
int main(){
key_t semkey2 = 0x201;
key_t semkey3 = 0x202;
int pid, pid1, pid2;
int semid;
if( (semid = initsem(semkey2)) < 0) printf("Error w powolywaniu semafora\n");
if( (semid2 = initsem(semkey3)) < 0) printf("Error w powolywaniu semafora\n");
fp = fopen("pidy","w"); fclose(fp); // wykasowanie zawartosci pliku pidy
/* przypisanie procedur dla sygnalow */
static struct sigaction act;
act.sa_handler = wstrzymanie;
sigaction(SIGUSR1, &act, NULL);
act.sa_handler = wznowienie;
sigaction(SIGUSR2, &act, NULL);
act.sa_handler = zakonczenie;
sigaction(SIGINT, &act, NULL);
act.sa_handler = czwarty;
sigaction(SIGCONT, &act, NULL);
switch( pid = fork() ){
case 0 :{
printf(" Proces 1 \n");
p(semid);
fp = fopen("pidy","a");
fprintf(fp,"%d\n",getpid());
fclose(fp);
v(semid);
switch( pid1 = fork() ){
case 0:{
printf(" Proces 2 \n");
p(semid);
fp = fopen("pidy","a");
fprintf(fp,"%d\n",getpid());
fclose(fp);
v(semid);
switch( pid2 = fork() ){
case 0:{
printf(" Proces 3 \n");
p(semid);
fp = fopen("pidy","a");
fprintf(fp,"%d\n",getpid());
fclose(fp);
v(semid);
while(1);
}
break;
default: //proces 2
while(1);
break;
}
}
break;
default: //proces 1
while(1);
break;
}
}
break;
}
return 0;
}
void wstrzymanie(){
int pid;
if( (fp2 = fopen("ins","w")) == NULL) printf("Error w tworzeniu pliku ins\n");
else{
fprintf(fp2, "wstrzymanie\n");
fclose(fp2);
if( (fp2 = fopen("pidy","r")) == NULL) printf("Error w otwieraniu pliku pidy\n");
else{
while( (fscanf(fp2, "%d\n", &pid)) != EOF){
if( pid != getpid() ) kill(pid, SIGCONT);
}
fclose(fp2);
}
}
pause();
}
void wznowienie(){
int pid;
if( (fp2 = fopen("ins","w")) == NULL) printf("Error w tworzeniu pliku ins\n");
else{
fprintf(fp2, "wznowienie\n");
fclose(fp2);
if( (fp2 = fopen("pidy","r")) == NULL) printf("Error w otwieraniu pliku pidy\n");
else{
while( (fscanf(fp2, "%d\n", &pid)) != EOF){
if( pid != getpid() ){
if( (kill(pid, SIGCONT)) == -1)
printf("Error w wysylaniu\n");
else{
printf("\t\tWysylanie kill sie powiodlo\n");
}
}
}
fclose(fp2);
}
}
}
void zakonczenie(){
int pid;
if( (fp2 = fopen("ins","w")) == NULL) printf("Error w tworzeniu pliku ins\n");
else{
fprintf(fp2, "zakonczenie\n");
fclose(fp2);
if( (fp2 = fopen("pidy","r")) == NULL) printf("Error w otwieraniu pliku pidy\n");
else{
while( (fscanf(fp2, "%d\n", &pid)) != EOF){
if( pid != getpid() ) kill(pid, SIGCONT);
}
fclose(fp2);
}
}
exit(0);
}
void czwarty(){
printf("Test\n");
char instrukcja[20];
printf("proces %d wyslano do mnie sygnal czwarty\n", getpid());
printf("proces %d przed sekcja krytyczna\n", getpid() );
//p(semid2);
/* sekcja krytyczna */
printf("proces %d w sekcji krytycznej\n", getpid() );
if( (fp2 = fopen("ins","r")) == NULL) printf("Error w otwieraniu pliku ins\n");
else{
printf("proces %d otworzyl plik i wczytuje dane\n", getpid() );
fscanf(fp2,"%s",instrukcja);
fclose(fp2);
printf("proces %d opuszcza sekcje krytyczna", getpid());
//v(semid2);
/* sekcja krytyczna */
printf("proces %d poza sekcja krytyczna\n");
printf("\nINSTRUKCJA TO: %s\n", instrukcja);
if( strcmp(instrukcja, "wstrzymanie") == 0 ){
pause();
}
if( strcmp(instrukcja, "zakonczenie") == 0 ){
exit(0);
}
if( strcmp(instrukcja, "wznowienie") == 0 ){
printf("\nwznowienie\n");
}
}
}
Przepraszam za rozjechanie się kodu.