PDA

Voir la version complète : aide avec la commande fork,, son dans une animation


dccd
19/04/2005, 14h10
Bonjour,

dans mon programe openGL, j'aimerais pouvoir lors d'une pression
sur une touche lancer un mp3. Puis en tapant une autre touche killer le player
tout en ayant mon animation qui tourne.

Pour ce faire, j'ai dans ma fonction qui gere les touches:

if (touche=='p')
{
pid=fork();
system(mplayer 01.mp3); // je suis sous linux et utilise mplayer comme player ....
pid=getpid(); // je recupere le pid de mplayer pour pouvoir le killer apres
}

if (touche=='k')
{
kill(pid,9); // on tue le mplayer
}

Malheureusement, je ne suis pas un expert en c++, et ne connais pas tres bien la commande fork.
Rien ne se passe ou alors je n'arrive pas a killer mon mplayer en pressant sur 'k' ....
Quelqu'un aurait-il une idee, un conseil svp ???

Merci

DccD

[Edit : déplacé, mis en forme]

Loulou
19/04/2005, 14h51
(tu devrais utiliser les balises CODE dans ton post... ça rend le code source bien plus lisible)
(tu aurais également dû poster dans le forum C / C++ -- fork() ce n'est pas de l'OpenGL)

Après execution de la commande fork(), tu as 2 processus s'executant exactement au même endroit du programme. Il faut donc faire juste après la différence entre le fils et le père.

id = fork();

if (id == 0)
{
// processus fils (si je me souviens bien...)
system(machin);
return; // on quitte pour ne pas executer le code du processus père
}

// processus père - on continue le programme normalement


Mais je ne pense pas que fork() soit adapté à ton problème, tu devrais plutôt te pencher sur l'utilisation des thread POSIX -- lance une recherche sur pthread_create et pthread_kill par exemple.

dccd
20/04/2005, 09h07
Salut,

tout d'abord merci pour ta réponse, je vais voir ce que j'arrive à faire.
Désolé pour le code que je n'ai pas écrit dans des balises (1er poste dans ce forum .....)
Je sais que la commande fork est du c++, mais comme j'en ai besoin
dans un programme opengl, je pensais que quelqu'un aurait
pu avoir le même problème ...... d'où mon post dans la section opengl.

anyway, sorry et merci,

DccD

PafLeCanif
20/04/2005, 13h49
J'ai comme un léger doute... n'essaierais-tu pas de manipuler la partie audio de ton programme en lançant/killant des applications tierces ?
si c'est le cas, c'est une mauvaise idée.
Tu devrais plutot utiliser des bibliothèques telles que SDL, FMOD, ou OpenAL...

dccd
25/04/2005, 17h23
Bon,

LouLou, j'ai essayé avec tes pthread_create et pthread_kill, mais je n'arrive pas à faire
ce que je veux faire .... merci quand même !

Sinon, pour répondre à PafLeCanif, je ne veux pas manipuler la partie audio de mon programme ....
Je veux juste faire ceci :

Je lance mon animation en opengl, puis si j'appuie sur la touche (disons "p") je lance mon player et joue un mp3
si j'appuie sur une autre touche (disons "s") le player s'arrète.
Tout ca bien sur en laissant tourner mon animation .....

C'est pour ca que je pensais que la commande fork pouvait m'être utile ... mais j'y arrive tout simplement pas ....

Anyway merci pour vos réponses .... Si quelqu'un a une autre idée, c'est bienvenue .

DccD

Loulou
25/04/2005, 20h29
Effectivement, si tu veux faire ça la manière de procéder sera légèrement différente. Tu ne pourras pas tuer un processus lancé avec la fonction system(). Enfin, je ne crois pas (je ne suis pas un pro des processus sous Linux). Si tu souhaites lancer un programme externe à ton appli puis tuer celui-ci plus tard, il faudra je pense créer un nouveau processus (du coup, avec fork() je pense que là ça marchera pas trop mal), puis faire executer ton programme dans le processus créé avec les fonctions exec*.

C'est peut-être n'importe quoi, mais perso c'est pas là que je creuserais. Si un pro de Linux pouvait passer par là et donner son avis ce serait pas plus mal :)

ploof
25/04/2005, 22h37
Rien ne se passe ou alors je n'arrive pas a killer mon mplayer en pressant sur 'k' ....


Si j'ai bien compris cette ligne mplayer se lance mais tu n'arrives pas à l'éteindre.
As-tu tenté de lancer la commande systeme KILL plutot que de la lancer directement à partir de ton code ? (avec un system(); peut-être)
Sait-on jamais...

Ma contribution à 2c

Joker-eph
26/04/2005, 19h58
tu connais pas l'ami portugais manuel ? :00000023:

bon plus sérieusement, fork (fourche en anglais) créer une bifurcation a un endroit d'un programme C. Après l'execution de la commande fork il faut donc gérer 2 processus (père et fils) dans le code.
On les distingue par la valeur de retour de fork().
Dans le père, fork() retourne le pid du fils, et dans le fils il retourne 0.

soit:


pid = fork();
if (pid == 0)
{
// action à réaliser dans le fils
}
else
{
//action à réaliser dans le père
}
return;
}


Voilà pour le fonctionnement de fork, maintenant la commande system est "bloquante", c'est à dire que le programme lance via un appel system la commande voulue (ici mplayer) et attend la fin de l'execution de la dite commande pour continuer. Donc si tu kill le processus, ce n'est pas mplayer que tu kill, mais le processus qui a lancé mplayer.

Donc analyse de ton code:


if (touche=='p')
{
pid=fork();

// 2 processus execute en même temps le code qui suit.

system(mplayer 01.mp3); // je suis sous linux et utilise mplayer comme player ....

// tu récupère dans chaque processus leur propre pid

pid=getpid(); // je recupere le pid de mplayer pour pouvoir le killer apres
}

if (touche=='k')
{
// le processus se tue lui même.

kill(pid,9); // on tue le mplayer
}






L'utilisation correcte de fork():


if (touche=='p')
{
pid=fork(); // 2 processus execute en même temps le code qui suit.

if ( pid == 0 )
{ // ceci ne s'execute que dans le fils

execlp("mplayer", "mplayer", "01.mp3", NULL ); // je suis sous linux et utilise mplayer comme player ....
// execlp ne retourne jamais, si l'appel echoue il y a un pb
perror("execlp");
exit(EXIT_FAILURE);
}

// ceci ne s'execute que dans le père

if (touche=='k')
{
// le processus se tue lui même.

kill(pid,9); // on tue le mplayer
}




Ceci devrait fonctionner mais tu risques de rencontrer d'autres pbs.
1) normalement il doit y avoir un wait() pour chaque fork dans le père.
2) j'imagine que ce code fait partie d'une boucle et donc tu risque de lancer plusieurs mplayer en même tps mais tu ne gardera que le dernier que tu as lancé.
3) si tu quitte il te faut killer les mplayer lancé.

Puisque tu code en C++ utilise un std::stack<int> pid pour stocker chaque numéro de processus que tu lances

Pour finir garde à l'esprit que ça reste assez "crade" comme solution.

dccd
27/04/2005, 09h22
Salut,



maintenant la commande system est "bloquante", c'est à dire que le programme lance via un appel system la commande voulue (ici mplayer) et attend la fin de l'execution de la dite commande pour continuer. Donc si tu kill le processus, ce n'est pas mplayer que tu kill, mais le processus qui a lancé mplayer.



Ok je ne savais pas que cette commande était bloquante ..... désolé



L'utilisation correcte de fork():


if (touche=='p')
{
pid=fork(); // 2 processus execute en même temps le code qui suit.

if ( pid == 0 )
{ // ceci ne s'execute que dans le fils

execlp("mplayer", "mplayer", "01.mp3", NULL ); // je suis sous linux et utilise mplayer comme player ....
// execlp ne retourne jamais, si l'appel echoue il y a un pb
perror("execlp");
exit(EXIT_FAILURE);
}

// ceci ne s'execute que dans le père

if (touche=='k')
{
// le processus se tue lui même.

kill(pid,9); // on tue le mplayer
}


Ceci devrait fonctionner mais tu risques de rencontrer d'autres pbs.
1) normalement il doit y avoir un wait() pour chaque fork dans le père.
2) j'imagine que ce code fait partie d'une boucle et donc tu risque de lancer plusieurs mplayer en même tps mais tu ne gardera que le dernier que tu as lancé.
3) si tu quitte il te faut killer les mplayer lancé.

Puisque tu code en C++ utilise un std::stack<int> pid pour stocker chaque numéro de processus que tu lances

Pour finir garde à l'esprit que ça reste assez "crade" comme solution.

Merci, à première vu ça marche !!!! Je vais essayer de paufiner le tout.
Merci aussi pour l'explication des erreurs de mon code, j'apprécie.


DccD

LXS
30/04/2005, 12h09
OMGG!

Non non non pas de fork() à chaque appui sur une touche!!
Quelle horreur, tous ces mécanismes systèmes lourds ( duplications/suppression de PCB ) pour jouer une petite musique :'(

Je m'étais attardé sur une petite librairie FMOD, je regarde si je l'ai pas virée par mégarde et la publierai... mais par pitié pas de fork().

Joker-eph
30/04/2005, 12h54
bah c'est clair que y a pas plus crade, mais bon ça à le mérite de marche.

Perso j'utilise la SDL, pour lire un wav c'est assez facile, pour plus compliqué il y a la SDL_mixer (qui ne fonctionne pas chez moi)

LXS
30/04/2005, 13h44
J'ai retrouvé le tutos, je le publie d'ici ce soir, même s'il est pas terminé...