2017-07-06 11 views
0

問題は次のとおりです。 2つのことをするpythonプログラムを呼び出します:rabbitmqサーバに接続し、2つのプロセスを起動するcプログラムを呼び出します。子によって継承されたPython RabbitMQ接続

pythonプログラムが終了すると、接続はまだ子供を担当して確立されます。

したがって、親が死んだ場合、子は親リソースを継承します。これは、Pythonスクリプトが終了したときに、私が得るものですnetstat -putan | grep rabbitmqip

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

をやっ

私はこのような場合に接続が失われると思います。

これはRabbitMQサーバーへの接続で発生すると思われます。通常のTCP接続では再生できません。

誰もこの問題を以前に持っていましたか?回避策はありますか?

Pythonコードは私のウサギの消費者になります.cプログラムは、ワーカーの仕事に基づいて産卵または殺されたバックグラウンドのスクリプトになります。私は消費者を殺すときにコネクションを確立することはできません。アクティブであるかどうかにかかわらず、子どもたちはキューから理解できないメッセージを受け取るためです。一例として

コード:

のPython:

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

子プログラム。

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); 
} 

答えて

1

は、UNIXでfork()を経由してサブプロセスを起動すると、子プロセスは親のオープン・ファイル記述子のすべてを継承します。子プロセスは、必要のない記述子を閉じる責任があります。

あなたのコードは2回、間接的にos.system()経由で2回コールしてから、再度Cコードで直接呼び出します。したがって、これを扱うには2通りの方法があります。

最初は、Cコードの子プロセスで不要な未使用のファイル記述子をすべて閉じることです。これは一般的には良い方法ですが、そうしないと、多くの子を生成して親のfdのコピーをすべて取得した場合、システムのファイル記述子が不足することは珍しくありません。

#include <unistd.h> 
#def MAXFD 256 

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

もう1つの選択肢は、ファイル記述子をPythonによって作成されたfork呼び出しで閉じておくことです。あなたがos.system()を呼び出す場合は、それを行うことができませんが、あなたはsubprocessモジュールとほぼ同等の呼び出しを行う場合は、このオプションを持っている:

from subprocess import Popen 

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

これが。 Popenは働いた。 – Illiax

関連する問題