[C/C++] Dialoguer avec un processus fils

Dialoguer avec un processus fils [C/C++] - C++ - Programmation

Marsh Posté le 03-05-2003 à 16:13:20    

Salut,
Je chercher si c'est possible, comment un child proc pourrait dialoguer avec son parent (échange d'infos, signaux,...).
Pour le moment je pensais le faire avec écriture dans un fichier mais bon ça doit pas être le top (le fils écrit dans le fichier, et le parent lit tant que...
merci
  ANT
 
edit: pour la création du process ben ça peut être ce que vous voulez, CreateProcess,...


Message édité par antsite le 03-05-2003 à 16:18:02
Reply

Marsh Posté le 03-05-2003 à 16:13:20   

Reply

Marsh Posté le 03-05-2003 à 16:20:40    

non, c'est pas possible, c'est la que tu vois que le C ca commence a dater, paske c'est pas tres pratique.
 
Je sais pas exactement comment ca marche, mais je sais qu'avec les stream (me souviens plus bien du nom, mais il me semble que c'est "stream" ), c'est possible, mais la il faut que tu fasses des recherches, paske j'y connais rien, je sais juste que ca existe et kya kavec ca que tu peux echanger des donnees entre pere et fils.
 
voila, jespere que ca t'aide, bon courage

Reply

Marsh Posté le 03-05-2003 à 16:22:24    

Tu peux voir du côté des pipes (qui existent sous unix et sous windows)

Reply

Marsh Posté le 03-05-2003 à 16:50:50    

me suis plante, le nom du truc en question c'est "threads"

Reply

Marsh Posté le 03-05-2003 à 16:52:03    

Oui en effet les pipes ont l'air d'être ce qu'il me faut mais, de plus dans msdn y a des exemples qui ont l'air pas mal mais vraiment trop compilqués! Personne peut me donner un bout de code comment le fils peut envoyer un signal au père (mettre une variable à 1 et que cette variable soit lisible par père & fils)...
 
http://msdn.microsoft.com/library/ [...] __pipe.asp
 
Merci à l'ame charitable qui me vulgarisera un des ces 2 exemples !  :hello:  

Reply

Marsh Posté le 03-05-2003 à 21:14:09    

Bon en fait les exemples sont pas trop durs, voila ce que j'en ai tiré mais évidemment ça marche pas:
test.cpp
 

Code :
  1. enum PIPES { READ, WRITE }; //READ = 0 ; WRITE = 1
  2. int main(void)
  3. {
  4. int hpipe[2];
  5. int termstat, pid;
  6. char hstr[20];
  7. _pipe(hpipe, 256, O_BINARY);
  8. itoa(hpipe[READ], hstr, 10);
  9. pid = spawnl(P_NOWAIT, "test2.exe", "test2.exe", hstr, NULL);
  10. printf("write\n" );
  11. for(int i=0;i<10;i++)
  12. {
  13. printf("-%d-\n", i);
  14. write(hpipe[WRITE], (char*)&i, sizeof(int));
  15. }
  16. cwait(&termstat, pid, WAIT_CHILD);
  17. close(hpipe[READ]);
  18. close(hpipe[WRITE]);
  19. return EXIT_SUCCESS;
  20. }


 
test2.cpp
 

Code :
  1. enum PIPES { READ, WRITE }; //READ = 0 ; WRITE = 1
  2. int main(int argc, char *argv[])
  3. {
  4. int hpipe[2];
  5. int i;
  6. hpipe[READ] = atoi(argv[1]);
  7. printf("\nread\n" );
  8. for(int n=0;n<10;n++)
  9. {
  10. read(hpipe[READ], (char*)&i, sizeof(int));
  11. printf("+%d+\n", i);
  12. }
  13. close(hpipe[READ]);
  14. close(hpipe[WRITE]);
  15. return EXIT_SUCCESS;
  16. }


 
 
sortie (quand je lance test.exe):
write
-0-
-1-
-2-
-3-
-4-
-5-
-6-
-7-
-8-
-9-
 
read
+1+
+1+
+1+
+1+
+1+
+1+
+1+
+1+
+1+
+1+
 
je ne comprends pas, merci de votre aide !

Reply

Marsh Posté le 03-05-2003 à 21:28:14    

C'est quoi cette fonction spawnl :??:

Reply

Marsh Posté le 04-05-2003 à 00:50:29    

Essaie de faire une zone de memoire commune (GlobalAlloc en win32)

Reply

Marsh Posté le 04-05-2003 à 10:52:13    

Heu si, c'est parfaitement possible : renseigne toi sur les segments de memoire partagés ('shm' sous les unices)
C'est une zone memoire que tu alloues dans un process avec un identifiant reutilisable par d'autres process :) tu peut y stocker et y lire à peu pres ce que tu veux ;)
 
 
le C n'est pas dépassé quand on sait s'en servir :hello:

Reply

Marsh Posté le 04-05-2003 à 12:08:51    

Oui en effet les shm ça à l'air très intéressant! Voila ce que j'ai trouvé, mais je suis sous windows et les fonctions shm... n'existent pas j'ai l'impression... comment faire ?
 
http://digilander.libero.it/robang [...] ool.c.html
 
Et pour mes pipes personnes n'a d'idée ?


Message édité par antsite le 04-05-2003 à 12:09:09
Reply

Marsh Posté le 04-05-2003 à 12:08:51   

Reply

Marsh Posté le 04-05-2003 à 12:46:45    

zarmaras a écrit :

me suis plante, le nom du truc en question c'est "threads"
 

c toi qui date pas le C

Reply

Marsh Posté le 05-05-2003 à 13:07:39    

up !

Reply

Marsh Posté le 05-05-2003 à 15:18:17    

ANT tu est sur unix ou windows ?
 
dans tous les cas tu peux utiliser soit des pipes soit des signaux, mais les signaux sont peu pratiques. Je parle ici pour unix car je sais pas du tout comment ca marche sous win on voit pas ca en cours, par contre sous unix c pas dur.
 
du meme coup si tu taff sou win tu pourrais me dire comment on crée un processus fils ? :)

Reply

Marsh Posté le 06-05-2003 à 09:36:56    

Salut,
ALors oui je suis sous windows mais si tu regardes le code que j'ai posté ci dessus je pense qu'il est standard donc tu vois pas pourquoi ça marche pas?
Ben pour créer un processus fils: CreateProcess, spawn/ exec,...
 
:hello:

Reply

Marsh Posté le 06-05-2003 à 10:05:52    

euh non c pas standard du tout ca depend du systeme sur lequel tu travaille... Sous unix tu utilises les primitives Unix (fork exec pipe select kill).
 
jpeu t'expliquer toute la theorie que tu veux et aussi la pratique sous unix mais sous windows je connais pas du tout. je pense que seules les primitives systemes changent, mais sinon le principe doit etre le meme.
 
:hello:

Reply

Marsh Posté le 06-05-2003 à 11:58:03    

excuse moi mais peux tu me dire où mon code n'est pas standard ?

Reply

Marsh Posté le 06-05-2003 à 13:34:46    

skoi spawnl ?
 
bah je connais pas CreateProcess moi en unix on utilise fork()

Reply

Marsh Posté le 07-05-2003 à 10:09:53    

Oui biensur CreateProcess c'est de l'API win32 mais spawnl tout comme execl,v ,e,... ben c'est standard (enfin je pense!)

Reply

Marsh Posté le 07-05-2003 à 12:24:23    

ok disons que c'est standard je vais regarder un peu au code des que j'ai 5 minutes ^^

Reply

Marsh Posté le 09-05-2003 à 22:58:41    

:sweat:

Reply

Marsh Posté le 10-05-2003 à 18:07:19    

:bounce:

Reply

Marsh Posté le 10-05-2003 à 18:12:59    

Ce sont bien 2 processus différents, ou seulement 2 threads d'un même processus ?
Dans le 2ème cas, c'est nettement plus simple :)

Reply

Marsh Posté le 10-05-2003 à 18:24:13    

euh si le prog test lance le prog test2, je comprend pas pourkoi ta des pipes dans test2 ...
 
ton prog test2 tu le fais lire et ecrire sur l'entree et la sortie standard
 
le prog test cree les 2 pipes, 1 qui fait pere -> fils et l'autre qui fait fils -> pere, ensuite dans le travail du fils tu redirige l'entree et la sortir standard vers les pipes (en unix la primitive c'est DUP() ou DUP2() ), apres le pere a pu ka lire et ecrire dans les pipes pour dialoguer avec son fils.
 
voila j'espere que j'ai ete clair, si c'eat pas le cas je recopierais ici un ptit exo qui dois trainer dans une de mes pochettes de cours ^^

Reply

Marsh Posté le 10-05-2003 à 18:29:22    

ANTSite a écrit :

Oui en effet les pipes ont l'air d'être ce qu'il me faut mais, de plus dans msdn y a des exemples qui ont l'air pas mal mais vraiment trop compilqués! Personne peut me donner un bout de code comment le fils peut envoyer un signal au père (mettre une variable à 1 et que cette variable soit lisible par père & fils)...
 
http://msdn.microsoft.com/library/ [...] __pipe.asp
 
Merci à l'ame charitable qui me vulgarisera un des ces 2 exemples !  :hello:  


 
j'avais pas vu ce message ;) detrompes toi les pipes c'est vraiment super simple, jvei trouver un bout de code qu'on a fait et jle pasterais ici des que j'ai le temps tu va voir c'est pas dur, t'aura juste a trouver l'equivalent windows des primitives unix dont je me sert :]

Reply

Marsh Posté le 10-05-2003 à 18:38:42    

zarmaras a écrit :

non, c'est pas possible, c'est la que tu vois que le C ca commence a dater, paske c'est pas tres pratique.
 
Je sais pas exactement comment ca marche, mais je sais qu'avec les stream (me souviens plus bien du nom, mais il me semble que c'est "stream" ), c'est possible, mais la il faut que tu fasses des recherches, paske j'y connais rien, je sais juste que ca existe et kya kavec ca que tu peux echanger des donnees entre pere et fils.
 
voila, jespere que ca t'aide, bon courage


 
heu le langage ça a aucune rapport avec les ipcs, mé ché pas grave...

Reply

Marsh Posté le 10-05-2003 à 18:49:14    

Jam Kuradoberi a écrit :

euh si le prog test lance le prog test2, je comprend pas pourkoi ta des pipes dans test2 ...
 
ton prog test2 tu le fais lire et ecrire sur l'entree et la sortie standard
 
le prog test cree les 2 pipes, 1 qui fait pere -> fils et l'autre qui fait fils -> pere, ensuite dans le travail du fils tu redirige l'entree et la sortir standard vers les pipes (en unix la primitive c'est DUP() ou DUP2() ), apres le pere a pu ka lire et ecrire dans les pipes pour dialoguer avec son fils.
 
voila j'espere que j'ai ete clair, si c'eat pas le cas je recopierais ici un ptit exo qui dois trainer dans une de mes pochettes de cours ^^


 
 
Oui voila nickel (laisse tomber les exemples MSDN). Oui je comprends en gros mais franchement j'aimerais bien un bout de code quand même!

Reply

Marsh Posté le 10-05-2003 à 19:53:36    

j'ai pas tout lu mais voici un exemple ou un processus pere communique avec son fils par pipe

Code :
  1. #include<stdio.h>
  2. #include<fcntl.h>
  3. void main (void)
  4. {
  5.   int i,j,l,a,b,k,m;
  6.   int tab[20];
  7.   int fich;
  8.   int p[2];
  9.   creat("tri.txt",00666);
  10.   pipe(p);
  11.   i=fork();
  12.   if (i!=0)
  13.   {
  14.     printf ("Processus pere\n" );
  15.     for (j=0;j<20;j++)
  16.     {
  17.       printf("\nEntrez le nombre %d : ",j+1);
  18.       scanf("%d",&a);
  19.       write(p[1],&a,sizeof(int));
  20.     }
  21.     close( p[1]);
  22.     wait(0);
  23.      fich= open ("tri.txt",O_RDONLY);     
  24.      read(fich,tab,20*(sizeof(int)));
  25.      for (k=0;k<20;k++)
  26. {
  27. printf ("%d\n",tab[k]);
  28. }
  29.    close (fich);         
  30. }
  31.   else
  32.   {
  33.     printf("\nprocessus fils\n" );
  34.     for (k=0;k<20;k++)
  35.     {
  36.        read(p[0],&b,sizeof(int));
  37.        l=0;
  38.        while ((l<k)&&(tab[l]<b))
  39.        {
  40.          l++;
  41.        }
  42.        for (m=k;m>l;m--)
  43.        {
  44.          tab[m]=tab[m-1];
  45.        }
  46.        tab[l]=b;
  47.     }
  48.     fich= open ("tri.txt",O_WRONLY);
  49.     printf("fichier : %d",fich);
  50.    
  51. write(fich,tab,20*(sizeof(int)));
  52. perror("write" );
  53.   close(fich);
  54.   }}


le processus pere saisi 20 nombres, les envoie a son fils par un pipe, le fils receptionne les nombres, les trie et les ecrits dans un fichier.
Ensuite le pere va lire les nombres dans le fichier et les affiches (ils sont donc triés).
Fonctionne sous Unix
 
EDIT : je viens de voir que t'etais sous win, mais cet exemple peut peut-etre t'aider quand meme a voir le principe de fonctionnement des pipes


Message édité par polo021 le 10-05-2003 à 19:56:37
Reply

Marsh Posté le 10-05-2003 à 20:17:07    

le problème tu vois c'est que j'ai en gros le même exemple sous windows avec msdn et c'est ce que j'ai posté (mon code plus haut) car ça ne marche pas. C'est sensiblement le même tu en penses quoi, pourquoi ça marche pas?
 
> Jam Kuradoberi, tu penses à mon exemple avec dup / dup2  :hello:

Reply

Marsh Posté le 10-05-2003 à 22:05:15    

Je ne sais pas si cela existe en win32 mais sinon tu pourrais utiliser des files de messages... là c'est franchement dur de faire plus simple !

Reply

Marsh Posté le 11-05-2003 à 00:16:43    

ANTSite a écrit :

le problème tu vois c'est que j'ai en gros le même exemple sous windows avec msdn et c'est ce que j'ai posté (mon code plus haut) car ça ne marche pas. C'est sensiblement le même tu en penses quoi, pourquoi ça marche pas?
 
> Jam Kuradoberi, tu penses à mon exemple avec dup / dup2  :hello:  


 
le problème avec le spawnl, c'est qu'un noveau processus est crée, mais un segment de donnée "initial".
 
quand tu forkes, le processus fils a une "copie" du segment de donnée du processus père.
quand tu spawnes, le process crée est un nouveau process tout clean (tu refais un père)
 
chez crosoft, ils ont décidé de favoriser l'approche multi-thread, au lieu de l'approche multi-process d'unix.
donc le mieux avec windows, c'est de faire de créer des threads.

Reply

Marsh Posté le 11-05-2003 à 00:18:50    

http://www.experts-exchange.com/Pr [...] 62938.html
 
symétriquement, il faut savoir que contrairement à unix/linux, toute communication inter-process est tué quand plus aucuns processus l'utilise (y'a un compteur d'utilisation)
 
alors que sous unix/linux, quand tu crées une mémoire partagée/sémaphore/etc etc..., quand tous tes process meurent sans les détruire, ils restent et fo passer derrière avec ipcs.


Message édité par bjone le 11-05-2003 à 00:20:46
Reply

Marsh Posté le 11-05-2003 à 00:22:51    

tiens un exemple de threads+sync que je me garde sous la main au cas où:
 
à coller dans un projet console/win32 (attention au stdafx.h au cas ou y'en aurait poa)
 

Code :
  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. // messages par threads
  6. char msg1[]="Thread1 AZERTY";
  7. char msg2[]="Thread2 UIOP";
  8. char msg3[]="Thread3 YAKAYA";
  9. CRITICAL_SECTION CSec; // (1) sync par section critique
  10. HANDLE hSemaphore;     // (2) sync par sémaphore
  11. HANDLE hMutex;         // (3) sync par mutex
  12. void timed_puts(char *s)
  13. {
  14. while( *s )
  15. {
  16.  putc(*s,stdout);
  17.  fflush(stdout);
  18.  Sleep(100 + (rand()&63) );
  19.  s++;
  20. }
  21. putc('\n',stdout);
  22. fflush(stdout);
  23. }
  24. DWORD WINAPI ThreadFunc( LPVOID lpParam )
  25. {
  26. int i;
  27. for( i = 0 ; i < 3 ; i++)
  28. {
  29.  //EnterCriticalSection(&CSec);              // (1) sync par section critique
  30.  //WaitForSingleObject(hSemaphore,INFINITE); // (2) sync par sémaphore
  31.  WaitForSingleObject(hMutex,INFINITE);       // (3) sync par mutex
  32.  /////////////////////////////////////////
  33.  timed_puts( (char*) lpParam );   // affichage
  34.  ////////////////////////////////////////
  35.  ReleaseMutex(hMutex);          // (3)
  36.  //ReleaseSemaphore( hSemaphore, 1, NULL); // (2)
  37.  //LeaveCriticalSection(&CSec);     // (1)
  38. }
  39. return 0;
  40. }
  41. int main(int argc, char* argv[])
  42. {
  43. //////////////////////////////////////
  44. ////////////////////////////////////// Création des primites de sync
  45. //////////////////////////////////////  
  46. // InitializeCriticalSection(&CSec);                // (1) sync par section critique
  47. // hSemaphore = CreateSemaphore( NULL,1,1,NULL );   // (2) sync par sémaphore
  48. hMutex=CreateMutex(NULL,false,NULL);             // (3) sync par mutex
  49. //////////////////////////////////////
  50. //////////////////////////////////////
  51. //////////////////////////////////////
  52. // Création des threads
  53. HANDLE hTh[3];
  54. DWORD dwTh[3];
  55. hTh[0]=CreateThread(NULL,0,ThreadFunc,&msg1,CREATE_SUSPENDED ,&dwTh[0]); // thread 0 suspendu
  56. hTh[1]=CreateThread(NULL,0,ThreadFunc,&msg2,0 ,&dwTh[1]); // thread 1 & 2 démarrent tout de suite
  57. hTh[2]=CreateThread(NULL,0,ThreadFunc,&msg3,0 ,&dwTh[2]);
  58. if( hTh[0]==NULL || hTh[1]==NULL || hTh[2]==NULL )
  59. {
  60.  printf("CreateThread() a echoue.\n" );
  61.  return 1;
  62. }
  63. ResumeThread(hTh[0]); // on autorise le thread 0 à s'éxécuter
  64. // ReleaseMutex(hMutex); // on lache tout via le mutex si il est créé avec true
  65. // attente fin de vie des threads (les 3 simultanés)
  66. WaitForMultipleObjects(3,hTh,true,INFINITE);
  67. // fermeture des handles de threads
  68. CloseHandle(hTh[0]);
  69. CloseHandle(hTh[1]);
  70. CloseHandle(hTh[2]);
  71. /////////////////////////////////////
  72. ///////////////////////////////////// destruction des primites de syncs
  73. /////////////////////////////////////
  74. CloseHandle(hMutex);
  75. // CloseHandle(hSemaphore);  
  76. // DeleteCriticalSection(&CSec);  
  77. //////////////////////////////////////
  78. return 0;
  79. }


Message édité par bjone le 11-05-2003 à 00:25:29
Reply

Marsh Posté le 11-05-2003 à 00:45:19    

Et là un exemple de mémoire partagée uniquement:
 
lancer deux fois l'éxécutable, le premier process crée, le deuxieme l'utilise.
 
ne pas oublier que toute mémoire partagée doit être accompagnée d'un sémaphore, hormis cas particuliers, sinon ton prof te mettera deux claques.
 
bin dans cet exemple y'a pas de sémaphore :D
 

Code :
  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include <iostream.h>
  5. #define SHMEMSIZE 64
  6. int main(int argc, char* argv[])
  7. {
  8. HANDLE hMapObject=NULL;
  9. char *Shm=NULL;
  10. BOOL ShmCreator;
  11. // création de l'objet partagé (pas fichier car INVALID_HANDLE_VALUE )
  12. if( hMapObject = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 
  13.         0, SHMEMSIZE, "bjone.shmtest" ), !hMapObject )
  14.  return 1;
  15. ShmCreator=(GetLastError() != ERROR_ALREADY_EXISTS);
  16. // mappage de l'objet en mémoire
  17. if( Shm = (char*)MapViewOfFile( hMapObject, FILE_MAP_WRITE, 0, 0, 0), !Shm )
  18.         return 2;
  19. printf( "Handle: %x\n"
  20.      "Offset memoire partagee: %p\n\n'q' pour quitter.\n\n",hMapObject,Shm);
  21. if( ShmCreator )
  22.  cout<<"Process createur de memoire partagee.\n";
  23. else
  24.  cout<<"Process non-createur de memoire partagee.\n";
  25. char BUFFER[SHMEMSIZE];
  26. do {
  27.  printf("%s\n",Shm);
  28.  cin.getline(BUFFER,SHMEMSIZE);
  29.  if( BUFFER[0] )
  30.   memcpy(Shm,BUFFER,SHMEMSIZE);
  31. } while( Shm[0]!='q');
  32. UnmapViewOfFile(Shm);
  33. CloseHandle(hMapObject);         
  34. return 0;
  35. }


 
voila je ne vois pas d'autres explications pour ce qui est du win32  :p  
 
si j'ai dit des conneries je m'en excuse à l'avance  :jap:
 
PS: bien évidemment dans le cas d'une appli multi-threadée, la mémoire partagée n'a aucun sens, puisque les threads utilisent le même segment de code & de donnée (mais contexte différent).


Message édité par bjone le 11-05-2003 à 00:51:27
Reply

Marsh Posté le 11-05-2003 à 00:58:10    

Très intéressant tout ca :jap:  :jap:

Reply

Marsh Posté le 11-05-2003 à 01:03:30    

au fait je viens de m'apercevoir que faire un CTRL-C & co peut faire péter les plombs au code :D [:sisicaivrai]

Reply

Marsh Posté le 11-05-2003 à 01:04:28    

BJOne a écrit :

au fait je viens de m'apercevoir que faire un CTRL-C & co peut faire péter les plombs au code :D [:sisicaivrai]  


 
a non c'est bon quand on est pas sous l'ide en mode debug  [:the one]

Reply

Marsh Posté le 11-05-2003 à 10:11:00    

Merci pour tout ça  :)  
Alors oui les threads disons que je m'en sert assez régulièrement donc j'ai pas trop de problème la dessus.
 
Par contre le shm je ne connais pas du tout, tu pourrais m'indiquer où employer sémaphore (en gros un WaitSingleObject qu'il faut non ?)
C'est que j'aimerais faire un truc propre quand même ;-)

Reply

Marsh Posté le 11-05-2003 à 13:16:57    

ANTSite a écrit :

Merci pour tout ça  :)  
Alors oui les threads disons que je m'en sert assez régulièrement donc j'ai pas trop de problème la dessus.
 
Par contre le shm je ne connais pas du tout, tu pourrais m'indiquer où employer sémaphore (en gros un WaitSingleObject qu'il faut non ?)
C'est que j'aimerais faire un truc propre quand même ;-)


 
bin sous unix (ou sous windows), si tu as deux process qui accèdent une mémoire partagée, suivant ce que contient la mémoire partagée il faut mettre un sémaphore lors de l'accès/modification de la mémoire partagée.
 
passke si tu as un process qui génére des informations dans la mémoire partagée, et l'autre qui les consommes, il peut y avoir un basculement de tâche au moment ou le process généreur d'info écrit dans la mémoire partagée.
 
et si au basculement on retombe sur le process consommateur, bah y va consommer quelque chose d'incomplet.
 
c'est un peu pareil pour des threads, si tu as une table qui sert d'échange d'info entre le process et ses threads, fo faire gaffe au cas où tu aurais des basculement de tâche pendant des modifications de la table d'échange.

Reply

Marsh Posté le 11-05-2003 à 13:43:26    

Ok, je vois, moi j'utilise Critical Section avec les threads, c'est pareil pour Shm ?

Reply

Marsh Posté le 11-05-2003 à 16:03:04    

oui, mais c'est carrément plsu chiant

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed