IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[Système] pcntl_fork() : duplication de processus ?


Sujet :

Langage PHP

  1. #1
    Membre averti Avatar de max44410
    Étudiant
    Inscrit en
    Juin 2003
    Messages
    426
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2003
    Messages : 426
    Points : 301
    Points
    301
    Par défaut [Système] pcntl_fork() : duplication de processus ?
    Bonjour,

    Je voudrais creer des processus pour executer des scripts php en parallele.
    Pour cela j'utilise la fonction pcntl_fork().

    voila mon code :

    check_ack_thread.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    #!/usr/bin/php -q
    <?php
    $d = true;
     
    for ($i = 0 ; $i < 10 ; $i++){
     
    	echo "loop [".$i."]\n\n";
    	$i_child_pid = pcntl_fork();
     
    	if ($d) echo "FORK PID: $i_pid\n";
     
    	if ($i_child_pid == -1) {
    		echo "Could not fork().  Exiting.\n";
    		exit;
    		}
     
    	if($i_child_pid){ // parent
    		if ($d) echo "Parent: child's pid is: ".$i_child_pid."\n";
    		if ($d) echo "A_Pids:\n";
     
    		# pcntl_wait($status);
    		sleep(1); 	// sleep to try and give each one a little breathing room
     
    		}
    	else
    		{      // child
    		system("./check_ack_test.php ".$i);		
    		}
    	}
    ?>
    Dans mon script "check_ack_test.php" je fais different sleep pour voir si mes thread fonctionne bien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #!/usr/bin/php -q
    <?php
     
    if ($_SERVER['argc'] > 1){
    	$i = $_SERVER['argv'][1];
    	echo "TIME script [".$i."] : ".date("H:i:s")."\n";
    	sleep($i/2);
    	echo "SELECT FROM table WHERE id = ".$i."\n";
    	echo "TIME END [".$i."] : ".date("H:i:s")."\n";
    	}
    ?>
    cependant si je regarde les processus sur mon server voila ce que j'obtiens :

    -bash-3.2$ ps -ef | grep php
    501 2949 2857 1 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2950 2949 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2952 2950 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2954 2952 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2956 2949 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2958 2950 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 2
    501 2960 2956 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2961 2960 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 2
    501 2962 2952 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2963 2962 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 3
    501 2964 2954 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2965 2964 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 3
    501 2967 2907 0 18:13 pts/1 00:00:00 grep php
    Autrement dit il me creer plusieurs processus avec le meme parametre:
    ./check_ack_test.php 2

    on le voit 2 fois.

    Ce que je veux c'est creer 10 processus avec 10 parametres differents.
    Je devrais avoir cela dans mes processus:

    -bash-3.2$ ps -ef | grep php

    501 2958 2950 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_thread.php
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 0
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 1
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 2
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 3
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 4
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 5
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 6
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 7
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 8
    501 2959 2958 0 18:13 pts/0 00:00:00 /usr/bin/php -q ./check_ack_test.php 9
    Je suis un peu perdu. J'ai commencer a lire de la doc sur fork, mais je ne vois toujours pas pourquoi mon script ne fonctionne pas comme je le voudrais.

    Merci

  2. #2
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    étant donné que ton argument est défini par ta variable, incrémenté grâce à ton itération, tu dois regarder de ce côté, vérifie la valeur de ta variable et tu verras où ça coince, tu peux t'aider en vérifiant sa valeur en sortie, et surtout en vérifiant tes conditions, en bref debug ton code, t'y verras plus clair.

  3. #3
    Membre averti Avatar de max44410
    Étudiant
    Inscrit en
    Juin 2003
    Messages
    426
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2003
    Messages : 426
    Points : 301
    Points
    301
    Par défaut
    Citation Envoyé par alceste Voir le message
    étant donné que ton argument est défini par ta variable, incrémenté grâce à ton itération, tu dois regarder de ce côté, vérifie la valeur de ta variable et tu verras où ça coince, tu peux t'aider en vérifiant sa valeur en sortie, et surtout en vérifiant tes conditions, en bref debug ton code, t'y verras plus clair.
    Je ne vois pas trop comment debugger plus mon code ...
    Une boucle for incremente tres bien les variables d'habitude.
    j'ai des IF et ELSE pour ne pas passer des certaines partie du code.
    Et j'ai beau regarder de tous les cotes, je ne vois pas comment resoudre mon probleme.

  4. #4
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    de toute manière, l'indice qui est la variable incrémenté par ta boucle, définie l'argument au lancement de ton programme, si l'indice est inchangé, ce que tu passes en argument ne sera pas ce que tu attends.
    donc au lieux de le lancer, affiche la ligne qui va être exécuter au niveau du shell, tu le verras bien par toi-même, il y'a peut-être corruption de ta variable à un moment ou un autre, et la meilleure façon de debugger quand tu ne trouves pas ce qui cloche en lisant le code, est d'afficher ce qu'il se passe exactement pour mieux comprendre ce qu'il se passe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    system("./check_ack_test.php ".$i);
    ça c'est ton instruction, qui lance ton programme, avec son argument, $i définie bien l'argument, si l'argument est le même, c'est que $i n'a pas changé, CQFD.

  5. #5
    Membre averti Avatar de max44410
    Étudiant
    Inscrit en
    Juin 2003
    Messages
    426
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2003
    Messages : 426
    Points : 301
    Points
    301
    Par défaut
    ok ..

    J'ai fait un ptit test pour voir ce que ca donne reellement.

    voila mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    #!/usr/bin/php -q
    <?php
    include_once('/data/www/html/*****/config.php');
     
    $d = true;
     
    for ($i = 0 ; $i < 10 ; $i++){ 
    	$i_cur++;
     
    	$i_pid = pcntl_fork();
    	if ($d) echo "FORK PID: $i_pid\n";
    	if ($i_pid == -1) {
    		echo "Could not fork().  Exiting.\n";
    		exit;
     
    		} elseif ($i_pid > 0) { // parent
    			if ($d) echo "Parent: child's pid is: $i_pid\n";
    			$a_pids[$i_pid] = $i;
    			if ($d) echo "A_Pids:\n";
    			if ($d) print_r($a_pids);
     
    			# pcntl_wait($status);
    			usleep(500000); 	// sleep to try and give each one a little breathing room
     
    		} else {
    			echo "Loop -> ".$i."\n";
    			$o_arbcore->get_mysql_connection()->exec("INSERT INTO `test_thread` (`child_insert`) VALUES (".$i.")");
     
    		} // if child
     
    	} // end for
    ?>
    Normalement je dois faire une insertion dans ma table test dans chaque processus fils. Noramlement il y a 10 processus fils.

    Dans ma base de donnee pour un lancement de script je dois avoir 10 enregistrements, or j'en ai exactement : 721

    Autrement dit, il y a un soucis ... je pense que je ne comprend pas le fonctionnement des fork.

    Est ce que vous avez des explications pour mon problemes.
    Merci

  6. #6
    Membre averti Avatar de max44410
    Étudiant
    Inscrit en
    Juin 2003
    Messages
    426
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2003
    Messages : 426
    Points : 301
    Points
    301
    Par défaut
    Salut,

    J'ai trouve une solution a mon probleme. En esperant que cela aidera certaines personnes. Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    $timeout = 3; #seconds
    $tmstmp_start = time();
     
    $npid = pcntl_fork(); // DETACH FROM TERMINAL AND BE REAPED BY INIT
     
    if ($npid==-1) 
    	die("Error: impossible to pcntl_fork()\n");
    elseif ($npid) 
    	exit(0); // THE GRANPA DIES
    else // MOTHER GOES ON TO MAKE CHILDREN
    	{
    	$children = 20;
     
    	for ($i = 1 ; $i <= $children ; $i++){
    		$pid = pcntl_fork();
     
     
    		if ($pid==-1) 
    			die("Error: impossible to pcntl_fork()\n");
    		elseif ($pid){
    			$pid_arr[$i] = $pid;
    			}
     
    		if (!$pid){ // CHILDREN
    			sleep(10);
    			echo "Parent : ".posix_getppid()." Child ".$i."\n";
    			//unset($pid_arr[$i]);
    			exit();
    		}
    	}
     
    # while all the children are not died
    while(($i_wait_pid = pcntl_wait($i_status, WNOHANG)) != -1) {
    	$diff = time() - $tmstmp_start;
    	# if the time is out ... we kill all the children
    	if ($diff >= $timeout){
    		foreach ($pid_arr as $pid){
    			// we are the parent and we wait for all children to die
    			if (posix_kill($pid, SIGTERM))
    				echo "I killed my son number : ".$pid."\n";
    			//pcntl_waitpid($pid, $status);
    			}
    		}
    	}
    Ca fonctionne bien, cependant lorsque le timeout ce fait, le processus parent essaye de tuer mes enfants plusieurs fois. Si quelqu'un a une idee a ce sujet ?

    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Système de communication inter processus
    Par robosara dans le forum Bibliothèques
    Réponses: 5
    Dernier message: 24/07/2013, 18h14
  2. Système de communication inter processus
    Par robosara dans le forum ALM
    Réponses: 1
    Dernier message: 24/07/2013, 18h13
  3. [Système] Comment "killer" un processus
    Par pjmorce dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 28/08/2008, 10h32
  4. [Système] Processus en tâche de fond
    Par yakotey dans le forum Langage
    Réponses: 11
    Dernier message: 09/01/2006, 00h09
  5. probleme de duplication de processus
    Par chachil dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 26/11/2005, 14h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo