[C] pause() i sygnały - problem

0

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:

  1. wysyłam SIGUSR1 do któregoś z procesów
  2. ten proces zapisuje w pliku "ins" ciąg znaków "wstrzymanie"
  3. następnie wysyła sygnał SIGCONT do dwóch pozostałych procesów aby te otworzyly sobie plik i przeczytały co mają zrobić.
  4. 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.

0

a po pause() to sie czasem nie budzil dopiero po SIGALRM ?

0

jesli piszesz dla siebie, to moze latwij byloby sterowac procesami poprzez socketa, czy tez pajpa ? chyba ze po prostu masz napisac tak a nie inaczej.

0

no niestety taką mam specyfikację zadania :-|

problem rozwiązany! zamiast pause() lepiej jest użyć sigpause(int sig). Parametr sig mówi, że sygnał o tym numerze nie będzie ignorowany.
w miejsce
pause();
wstawiam:
sigrelse(SIGCONT);
sigpause(SIGUSR2);
ale mimo to wydaje mi się program w pierwotnej wersji też powinien działać

PS. sigsuspend to też dobre rozwiązanie

1 użytkowników online, w tym zalogowanych: 0, gości: 1