2017-07-06 2 views
0

Le problème est le suivant. Appelez un programme python qui fait deux choses: se connecter à un serveur rabbitmq et appelle un programme c qui engendre deux processus.Connexion Python RabbitMQ héritée par un enfant

Lorsque le programme python se termine, la connexion est toujours établie en charge d'un enfant. Par conséquent, un enfant hérite de sa ressource parent lorsque le parent meurt.

faire un netstat -putan | grep rabbitmqip

tcp 0 0 localhost:39744 rabbitmqip:5672 ESTABLISHED 25693/child 

C'est ce que je reçois quand le script python terminé.

J'imagine que la connexion serait perdue dans un cas comme celui-ci.

Cela semble se produire avec des connexions à un serveur RabbitMQ, nous ne pouvons pas reproduire avec des connexions TCP régulières.

Quelqu'un a-t-il déjà eu ce problème? existe-t-il une solution de contournement?

Le code python serait mon consommateur de lapin et le programme c serait des scripts en arrière-plan qui sont engendrés ou tués en fonction du travail du travailleur. Je ne peux pas avoir la connexion établie quand je tue le consommateur, indépendamment des spawns étant actifs ou pas parce qu'alors les enfants recevraient des messages qu'ils ne comprennent pas de la file d'attente.

Code comme exemple:

Python:

connection = pika.BlockingConnection(pika.ConnectionParameters(host='RabbitServer')) 
print ("Starting Child...") 
system("/home/path/test/child") 
print ("Done") 

programme des enfants.

pid_t pstartId, sessionId; 

// Fork 1 
pstartId = fork(); 
if (pstartId < 0) { 
    printf("The System can not create a proccess. \n"); 
    perror("fork"); 
    exit(EXIT_FAILURE); 
} 

if (pstartId > 0) { exit(EXIT_SUCCESS);} 

// Fork 2 
pstartId = fork(); 
if (pstartId < 0) { 
    printf("The System can not create a proccess. \n"); 
    perror("fork"); 
    exit(EXIT_FAILURE); 
} 

if (pstartId > 0) {exit(EXIT_SUCCESS);} 

if ((sessionId = setsid()) < 0) { 
    printf("The System can not set a id session. \n"); 
    perror("setid"); 
    exit(EXIT_FAILURE); 
} 

if (chdir("/") < 0) { 
    printf("The System can not change dir /. \n"); 
    perror("chdir"); 
    exit(EXIT_FAILURE); 
} 

while(1){ 
    syslog(LOG_INFO, "I'm a child"); 
    sleep(1); 
} 

Répondre

1

Lorsque vous frayer un sous-processus via fork() dans unix le processus enfant hérite de tous les descripteurs de fichiers du parent. Le processus fils est responsable de la fermeture des descripteurs dont il n'a pas besoin.

Votre code est appel fourchette deux fois, une fois indirectement via os.system(), puis directement dans votre code C. Vous avez donc deux façons de gérer cela:

La première consiste à fermer tous les descripteurs de fichiers inutilisés dont vous n'avez pas besoin dans le processus fils de votre code C. C'est généralement une bonne pratique, si vous ne le faites pas il n'est pas rare de manquer de descripteurs de fichiers dans votre système si vous générez de nombreux enfants et qu'ils ont tous des copies des fds de leurs parents.

#include <unistd.h> 
#def MAXFD 256 

void close_fds() { 
    int i; 
    for (i = 3; i < MAXFD; i++) { 
    close(i); 
    } 
} 

L'autre option serait d'avoir descripteurs de fichiers fermés dans l'appel de la fourche faite par Python. Vous n'êtes pas en mesure de le faire si vous appelez os.system(), mais vous avez cette option si vous faites l'appel presque équivalent avec le module subprocess:

from subprocess import Popen 

Popen("/home/path/test/child", close_fds=True).wait() 
+0

Ce. Popen a travaillé. – Illiax