[C] segnali tra processi in ciclo

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
neofitabo
Prode Principiante
Messaggi: 6
Iscrizione: sabato 4 febbraio 2017, 10:41
Sesso: Maschile

[C] segnali tra processi in ciclo

Messaggio da neofitabo »

Salve sto svolgendo un esercizio:
Scrivere un programma in C in cui vengano effettuate le seguenti operazioni:
-un processo legge da tastiera un intero n, con pari;
-crea n processi figli, scrive i pid dei figli in un nuovo file figli.dat e invia un segnale SIGUSR1
a tutti i figli;
-appena ricevuto il segnale dal padre, il processo p0 invia il segnale SIGUSR2 al processo p2, che dopo averlo ricevuto,
lo invia al prossimo processo di indice pari. L' ultimo processo di indice pari blocca la catena.Lo stesso fanno i processi
dispari a partire da p1.

Riscontro problemi nell' implementazione dell' ultimo punto, trovo inconcepibile che un processo non ancora inizializzato possa settare un handler per ricevere il segnale. Dunque confido in un' idea vostra. Vi posto la mia soluzione sbagliata per l' ultimo punto. Grazie a chiunque mi aiuterà.

Codice: Seleziona tutto


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>

void gest(int pam);

int main()
{
	int n,fd;
	char buff[5];
	
	do
	{
		printf("inserisci numero intero pari\n");
		scanf("%d",&n);
		if(n%2!=0)
		{
			perror("numero inserito dispari\n");
		}
	}
		while(n%2!=0);
		
	pid_t pid[n];
	
	for(int i=0;i<n;i++)
	{
		pid[i]=fork();
		
		if(pid[i]==0)
		{
			printf("figlio %d mi metto in attesa della kill\n",i);
			signal(SIGUSR1,gest);
			pause();
			if(i%2==0)
			{
				/* NON EFFICACE
				if(i>0)
				{
					signal(SIGUSR2,gest);
					pause();
				}
				kill((getpid()+2),SIGUSR2);
				*/
			}
			exit(i);
			
		}
		
		else
		{
			sprintf(buff,"%d\n",pid[i]);
			fd=open("figli.dat",O_CREAT|O_RDWR|O_APPEND,0777);
			write(fd,&buff,strlen(buff));
			sleep(1);
			kill(pid[i],SIGUSR1);
			waitpid(pid[i],NULL,0);
		}
	}
	
		
}

void gest(int pam)
{
	if(pam==SIGUSR1)
	{
		printf("ho ricevuto il segnale 1...\n");
		
	}
	else
	{
		printf("ho ricevuto il segnale 2\n");
	}
}

melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: [C] segnali tra processi in ciclo

Messaggio da melfnt »

Codice: Seleziona tutto

kill((getpid()+2),SIGUSR2);
Non funziona, perché il pid del prossimo processo lanciato non è necessariamente quello del processo corrente aumentato di uno, per vari motivi legati allo scheduler del sistema operativo.

Però hai scritto un file con tutti i pid, a qualcosa serviranno no?
(;
neofitabo
Prode Principiante
Messaggi: 6
Iscrizione: sabato 4 febbraio 2017, 10:41
Sesso: Maschile

Re: [C] segnali tra processi in ciclo

Messaggio da neofitabo »

Ciao, sì sicuramente è un' ottima osservazione quella del pid. Devo dire che ho comunque risolto il problema primario che non era questo (lo scheduler mi creava i processi sequenzialmente). Credo che il problema era dovuto al fatto che io volessi fare quelle operazioni all' interno di un singolo for, cosa logicamente non giusta.
Tuttavia posto la soluzione "corretta":

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>

void gest(int pam);
void gest2(int p2);

int main()
{
	int n,fd;
	char buff[5];
	
	
	do
	{
		printf("inserisci numero intero pari\n");
		scanf("%d",&n);
		if(n%2!=0)
		{
			perror("numero inserito dispari\n");
		}
	}
		while(n%2!=0);
		
	pid_t pid[n];
	
	for(int i=0;i<n;i++)
	{
		pid[i]=fork();
		
		if(pid[i]==0 )
		{
				if(i==0 )
				{
					printf("figlio %d mi metto in attesa della kill\n",getpid());
					signal(SIGUSR1,gest);
				}
				if(i==1)
				{
					printf("figlio %d mi metto in attesa della kill\n",getpid());
					signal(SIGUSR1,gest2);
				}
				if(i>1)
				{
					signal(SIGUSR2,gest);
					signal(SIGUSR1,SIG_IGN);
				}
				
				
				
				pause();
				
			
			
			
			
			
			
			
			
		}
		
		else
		{
			sprintf(buff,"%d\n",pid[i]);
			fd=open("figli.dat",O_CREAT|O_RDWR|O_APPEND,0777);
			write(fd,&buff,strlen(buff));
			printf("pid%d=%d \n",i,pid[i]);
			
			
			//waitpid(pid[i],NULL,0);
		}
	}
	
	for(int j=0;j<n;j++)
	{
		sleep(1);
		kill(pid[j],SIGUSR1);
		waitpid(pid[j],NULL,0);
	}
	
	
	
		
}

void gest(int pam)
{
	if(pam==SIGUSR1)
	{
		printf("sono il processo %d ho ricevuto il segnale 1 da mio padre...\n",getpid());
		printf("adesso mando una kill a %d\n",(getpid()+2));
		kill((getpid()+2),SIGUSR2);
		exit(0);
		
		
	}
	else
	{
		printf("sono il processo %d ho ricevuto il segnale 2 da %d\n",getpid(),(getpid()-2));
		kill((getpid()+2),SIGUSR2);
		exit(0);
		
		
	}
}

void gest2(int p2)
{
	if(p2==SIGUSR1)
	{
		printf("sono il processo %d ho ricevuto il segnale 1 da mio padre...\n",getpid());
		printf("adesso mando una kill a %d\n",(getpid()+2));
		kill((getpid()+2),SIGUSR2);
		exit(0);
	}
	else
	{
		printf("sono il processo %d ho ricevuto il segnale 2 da %d\n",getpid(),(getpid()-2));
		kill((getpid()+2),SIGUSR2);
		exit(0);
	}
}
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 5 ospiti