Pagina 1 di 1

[C] segnali tra processi in ciclo

Inviato: lunedì 13 febbraio 2017, 8:40
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");
	}
}


Re: [C] segnali tra processi in ciclo

Inviato: giovedì 16 febbraio 2017, 20:41
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?
(;

Re: [C] segnali tra processi in ciclo

Inviato: giovedì 23 febbraio 2017, 20:18
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);
	}
}