Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 02/02/2008, à 17:20

manta

Débutant en signaux

Salut à tous wink
Je débute en signaux sous ce bon vieux langage C et j'arrive meme pas a faire des trucs tout simples...
Je ne comprends pas a quoi sert la fonction kill() ni comment s'en servir.
Par exemple si j'ai envie de faire un fils avec un p=fork() et qu'apres dans le code du pere je fais un printf("%d",kill(p, 0)); cela m'affiche tjrs 0 que le fils soit mort ou pas...

Hors ligne

#2 Le 02/02/2008, à 20:36

obiwankennedy

Re : Débutant en signaux

en faite, kill porte assez mal sont nom.
C'est une fonction qui envoie un signal à  un processus. (mais ce signal n'ordonne pas forcement au processus de se tuer).

kill(p, 0);
N'envoie aucun signal mais vérifie juste quelques trucs donc je pense que si tu envoyais un vrai signal,  une erreur surviendra peut être sinon dans le man de la fonction

man 2 kill

il est aussi expliqué que le code erreur est retourné dans "errno".

#include <iostream>
#include <signal.h>
using namespace std;

void fonctionsignal(int sig)
{
	signal(SIGUSR1,fonctionsignal);/*important de remettre le signal dans lafonction. certain vieille version du noyau le suprime et du coup le signal ne marche qu'une fois*/
	cout << "ceci est un bon exemple "<< endl;
}
void tuer(int sig)
{ 	
	signal(SIGUSR2,tuer);
	cout << "pour comprendre "<< endl;	
}
int pid;
int pid3;
int compteur=0;
int res;
int main(int n, char *params[])
{
		signal(SIGUSR1,fonctionsignal);
		signal(SIGUSR2,tuer);
	
	res=fork();
	if(res==0)//fils
	{
		
		while(1)
		{
			
		}
		
	}
	else if(res>0)//pere
	{
	
		
		
	while(true)
		{
		
			kill(res,SIGUSR1);
			sleep(1);
			kill(res,SIGUSR2);
			sleep(1);
					
		}
		
	}
	else
		cout << "erreur" << endl;
	
	
}

Ce code c'est du C avec juste les affichages en C++.
En gros, le père crée un fils. Ce fils tourne en boucle et à  redéfini 2 signaux.
A intervalle régulière, le père lance un signal sur son fils et son fils affichent tel ou tel message selon le signal émit.

Dernière modification par obiwankennedy (Le 02/02/2008, à 20:42)


Dans mes logiciels, j'écris ton nom.
SGNGD: SvgGd is Not GD
Rolisteam

Hors ligne

#3 Le 03/02/2008, à 13:03

manta

Re : Débutant en signaux

Merci pour ton aide ce code m'a bien servi.

Mais la je dois faire un programme qui crée 2 fils, envoie SIGUSR1 au fils 1, qui le renvoie au pere, qui le renvoie au fils 2 etc...

j'ai tenté ça

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

int bor_signal (int sig, void (*h)(int), int options)
{
	struct sigaction s;
	s.sa_handler = h;
	sigemptyset (&s.sa_mask);
	s.sa_flags = options;
	
	return sigaction (sig, &s, NULL);
}

void capte(int sig, int pid)
{
	switch(sig) {
		case SIGUSR1 : kill(pid, sig);  
			printf("signaux recu, renvoi vers %d\n",pid); break;
	}
	return;
}

int main()
{
	int p1, p2;
	
	p1=fork();
	if(p1<0) { perror("fork"); exit(1); }
	if(p1==0)
	{
		printf("le fils 1 est %d\n", getpid());
		capte(SIGUSR1, getppid());
		exit(0);
	}
	
	p2=fork();
	if(p2<0) { perror("fork"); exit(1); }
	if(p2==0)
	{
		printf("le fils 2 est %d\n", getpid());
		kill(p1,SIGUSR1);
		
		capte(SIGUSR1, p1);
		exit(0);
	}
	
	printf("le pere est %d\n", getpid());
	capte(SIGUSR1, p2);
	sleep(10);
	
	
	return 0;
}

mais ça ne fonctionne pas, tandis que si j'enleve le kill() dans la fonction capte le pere et le fils 2 vont recevoir un signal alors que je ne leur envoie rien...

Hors ligne

#4 Le 03/02/2008, à 19:39

obiwankennedy

Re : Débutant en signaux

je ne suis pas sur d'avoir bien compris ton problème mais ce que j'en ai compris. J'aurai fait ça (bon le code est à  revoir; il y a sûrement des variables en trop et des possibilités d'optimisation).

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

void fonctionsignal(int sig)
{
    signal(sig,fonctionsignal);
printf("signal: le fils 1 est %d\n", getpid());
	kill(getppid(),sig);
	
}
void fonctionsignal2(int sig)
{
    signal(sig,fonctionsignal2);
printf("signal: le fils 2 est %d\n", getpid());
	kill(getppid(),sig);
	
}
int p1, p2,pere;
int index;
int pid[2];

void signalpere(int sig)
{
	signal(sig,signalpere);
printf("le pere est %d\n", getpid());
	kill(pid[index++],sig);
		if(index>1)		
			index=0;
	
}


int main()
{

	index=0;

    
    pere=getpid();
    pid[0]=fork();
    pid[1]=fork();
    if((pid[0]<0)||( pid[1]<0)) { perror("fork"); exit(1); }
    if(pid[0]==0)
    {
	signal(SIGUSR1,fonctionsignal);
        printf("le fils 1 est %d\n", getpid());
		while(1)
		{
		sleep(1);
		}
    }
    else if(pid[1]==0)
    {
	signal(SIGUSR1,fonctionsignal2);
        printf("le fils 2 est %d\n", getpid());
		while(1)
		{
		sleep(1);			
		}
    }
    else if(pid[0]>0)
	{
		printf("le pere est %d\n", getpid());
		signal(SIGUSR1,signalpere);
		kill(pid[index++],SIGUSR1);
		while(1)
		{
		sleep(1);			
		}
	}

    return 0;
}

voilà .

Dernière modification par obiwankennedy (Le 03/02/2008, à 19:41)


Dans mes logiciels, j'écris ton nom.
SGNGD: SvgGd is Not GD
Rolisteam

Hors ligne

#5 Le 04/02/2008, à 00:03

manta

Re : Débutant en signaux

Merci bcp pour vos réponses ça me fait bien avancer je commence a mieux comprendre...

J'ai une autre petite question je ne comprends pas tres bien comment marche la fonction execlp()
je m'explique :
si je fais un execlp("ls","ls","-t",NULL); ça marche mais un execlp("ls","ls","-t"); ne fonctionne pas
tandis que execlp("head", "head", "-15"); marche mais pas execlp("head", "head", "-15", NULL);

Hors ligne

#6 Le 05/02/2008, à 10:06

Aurel34

Re : Débutant en signaux

manta a écrit :

Merci bcp pour vos réponses ça me fait bien avancer je commence a mieux comprendre...

J'ai une autre petite question je ne comprends pas tres bien comment marche la fonction execlp()
je m'explique :
si je fais un execlp("ls","ls","-t",NULL); ça marche mais un execlp("ls","ls","-t"); ne fonctionne pas
tandis que execlp("head", "head", "-15"); marche mais pas execlp("head", "head", "-15", NULL);

de toute façon "head -15" ça ne doit pas faire grand chose...

sinon il faut TOUJOURS finir ta liste d'arguments par (char*)NULL (le (char*) est demandé dans le man, pour éviter tout problème d'archi/pile... je le mets, mais bon NULL tout seul ça marche aussi chez moi)

/* main.c
 * ushu <noce@pcrob156.lirmm.fr>
 *
 * gcc -o test main.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[0])
{
	if (argc==1)
		execlp("ls",argv[0],"-l",(char*)NULL);
	else
		execlp("head",argv[0],"-n","15",argv[1],(char*)NULL);
	exit(0);
}

#7 Le 05/02/2008, à 10:08

Aurel34

Re : Débutant en signaux

(et c'est

int main(int argc, char *argv[])

bien sûr)