Zatrzymanie procesów potomnych i wznowienie, sygnały

0

Siemka, mam problem odnośnie linuxa i C, potrzebuje zatrzymać program na sygnał SIGUSR1 (proces zatrzymany wysyła sygnał do pozostałych i je zatrzymuje), oraz wznowić na SIGUSR2... Najlepszą opcją wydaje się być pause() ale niezbyt chce mi to działać.
Dotychczas działa zatrzymanie wszystkich procesów kiedy PID jakikolwiek podam, z wyjątkiem procesu macierzystego, ten nie chce się 'zatrzymać'...
Nie działa wznawianie zaś np. Zatrzymuje p1, i wznowić go moge tylko podając p1 pid, a potrzebuje go wznowić z pid2 pid3 [...].

Prosze kod:


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>

int mpid, pid1, pid2, pid3, shmid;
sem_t *sem1;
int zatrzymaj = 0;

	int signo;
	sigset_t set;
   

void zakonczPrace(int sig){
	psignal(sig,"\nOtrzymalem sygnal");
	
	kill(pid1, SIGINT);
	kill(pid2, SIGINT);
	kill(pid3, SIGINT);
	usleep(100);
	shmctl(shmid, IPC_RMID, NULL);
	sem_destroy(sem1);
	exit(0);
	return;
}
void zakonczPraceDzieci(int sig){
	kill(mpid, SIGINT);
	usleep(100);
	exit(0);
	return;
}

void stopM(int sig){
	psignal(sig,"\nOtrzymalem sygnal, STOP!");
	kill(pid1, SIGUSR1);
	kill(pid2, SIGUSR1);
	kill(pid3, SIGUSR1);
	
	sigemptyset(&set);
    sigaddset(&set, SIGUSR2);


	pause();

	return;
}
void stopD(int sig){
	kill(mpid, SIGUSR1);
	
	sigemptyset(&set);
    sigaddset(&set, SIGUSR2);
	pause();
	
	return;
}

int main(int argc, int *argv[]){
	mpid = getpid();
	printf("PPM rozpoczyna prace: %i\n", getpid());


	signal(SIGINT, zakonczPrace);
	
	signal(SIGUSR1,stopM);



	if((pid1=fork())){
		if((pid2=fork())){
			if((pid3=fork())){
				
			}else{
				//PP3
				signal(SIGINT,zakonczPraceDzieci);
				signal(SIGUSR1,stopD);

			}
		}
		else {
			//PP2

			signal(SIGINT,zakonczPraceDzieci);
			signal(SIGUSR1,stopD);
		
			
			}
	}
	else {
		//PP1
		signal(SIGINT,zakonczPraceDzieci);
		signal(SIGUSR1,stopD);

		}

	}
	
	return 0;
}

0

Poprawiłem, najbardziej czytelnie jak się da

0

oraz wznowić na SIGUSR2

Proces uruchamiasz funkcją execl. Potrzebujesz do tego ścieżki do binarki, którą chcesz uruchomić, pamiętaj również o przekazaniu przynajmniej dwóch parametrów, pierwszym jest nazwa aplikacji a drugim bądź ostatnim jest null zero.

Nie działa wznawianie zaś np. Zatrzymuje p1, i wznowić go moge tylko podając p1 pid, a potrzebuje go wznowić z pid2 pid3

No to działa czy nie działa? Ogólnie nie wiem, jak Ci się udało wznowić proces mając tylko pid, bo z user space'a nie da zarezerwować PIDa dla procesu. Możesz proces uruchomić, odczytać jego PID, zmienić ścieżkę do PID i to wszystko.

0
several napisał(a):

oraz wznowić na SIGUSR2

Proces uruchamiasz funkcją execl. Potrzebujesz do tego ścieżki do binarki, którą chcesz uruchomić, pamiętaj również o przekazaniu przynajmniej dwóch parametrów, pierwszym jest nazwa aplikacji a drugim bądź ostatnim jest null zero.

Nie działa wznawianie zaś np. Zatrzymuje p1, i wznowić go moge tylko podając p1 pid, a potrzebuje go wznowić z pid2 pid3

No to działa czy nie działa? Ogólnie nie wiem, jak Ci się udało wznowić proces mając tylko pid, bo z user space'a nie da zarezerwować PIDa dla procesu. Możesz proces uruchomić, odczytać jego PID, zmienić ścieżkę do PID i to wszystko.

Wiesz co, poradziłem sobie trochę inaczej, aczkolwiek został mi jeden mały szkopuł, że to rozwiązanie może zostać użyte tylko jeden raz po uruchomieniu programu... Zastanawiam się teraz jak to 'ogarnąć', aby te akcje, zatrzymania i wznawiania były możliwe wiele razy.... nie jestem pewien czy sprowadzi się to tylko do zmiennych usr2, zatrzymaj. Jeśli ktoś ma jakiś pomysł to chętnie przygarnę.

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
 
#define READ 0
#define WRITE 1

int mpid, pid1, pid2, pid3, shmid;

int zatrzymaj = 0;
int usr2 = 0;
sigset_t set, oldmask;
 
void zakonczPrace(int sig){
    psignal(sig,"\nOtrzymalem sygnal");
   
    kill(pid1, SIGINT);
    kill(pid2, SIGINT);
    kill(pid3, SIGINT);
    usleep(100);
    shmctl(shmid, IPC_RMID, NULL);
    sem_destroy(sem1);
    exit(0);
}
void zakonczPraceDzieci(int sig){
    kill(mpid, SIGINT);
    usleep(100);
    exit(0);
}
 
void stopM(int sig){
    printf("\nMacierzysty: Otrzymalem sygnal: %d \n", sig);
    fflush(stdout);
 
    if(zatrzymaj)
        return;
 
    zatrzymaj = 1;
 
    kill(pid1, SIGUSR1);
    kill(pid2, SIGUSR1);
    kill(pid3, SIGUSR1);
	
	sigemptyset(&set);
    sigaddset(&set, SIGUSR2);
    sigprocmask(SIG_BLOCK, &set, &oldmask);
    while(!usr2){
		sigsuspend(&oldmask);
	}
	kill(pid1, SIGUSR2);
	kill(pid2, SIGUSR2);
	kill(pid3, SIGUSR2);

    sigprocmask(SIG_UNBLOCK, &set, NULL);
	
}
 
void stopD(int sig){
    printf("\nWysylam sygnal SIGUSR1 do: %d\n", getpid());
    fflush(stdout);
 
    kill(mpid, SIGUSR1);
   
    sigemptyset(&set);
    sigaddset(&set, SIGUSR2);
    sigprocmask(SIG_BLOCK, &set, &oldmask);
    while(!usr2){
		sigsuspend(&oldmask);
	}
	kill(pid1, SIGUSR2);
	kill(pid2, SIGUSR2);
	kill(pid3, SIGUSR2);
	kill(mpid, SIGUSR2);
    sigprocmask(SIG_UNBLOCK, &set, NULL);
	
}
 
void usr2Handler(int sig){
    usr2 = 1;
}
 
int main(int argc, char *argv[]){
    mpid = getpid();
    printf("Program rozpoczyna prace: %i\n", getpid());

 
    signal(SIGINT, zakonczPrace);
   

/* Kontrola sygnałów wstrzymania i wznowienia procesu głównego */
    signal(SIGUSR1,stopM);
    signal(SIGUSR2,usr2Handler);
 

 
    if((pid1=fork())){
        if((pid2=fork())){
            if((pid3=fork())){
               
            }else{
                //PP3
               
                signal(SIGINT,zakonczPraceDzieci);
                signal(SIGUSR1,stopD);
                signal(SIGUSR2,usr2Handler);

        }
        else {
            //PP2
 
            signal(SIGINT,zakonczPraceDzieci);
            signal(SIGUSR1,stopD);
            signal(SIGUSR2,usr2Handler);
   
           
        }//PP2
    }
    else {
        //PP1
 
        signal(SIGINT,zakonczPraceDzieci);
        signal(SIGUSR1,stopD);
        signal(SIGUSR2,usr2Handler);

    return 0;
}

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