2017-07-06 52 views
0

問題如下。 調用一個執行兩件事情的Python程序:連接到rabbitmq服務器並調用產生兩個進程的c程序。由孩子繼承的Python RabbitMQ連接

當python程序結束時,連接仍然建立在負責孩子。

因此,當父母死亡時,孩子會繼承其父資源。

netstat -putan | grep rabbitmqip

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

這是我所得到的,當Python腳本完成。

我會想象在這種情況下連接會丟失。

這似乎與連接到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()一個子進程的子進程繼承了所有家長的打開文件描述符。子進程負責關閉它不需要的描述符。

您的代碼通過os.system()間接調用叉兩次,然後直接在您的C代碼中直接調用。所以你有兩種處理方法:

第一種方法是關閉所有在C代碼的子進程中不需要的未使用的文件描述符。這通常是一種很好的做法,如果你不這樣做的話,如果你產生了許多孩子並且他們都獲得了他們父母的fds副本,那麼在系統中用完文件描述符並不罕見。

#include <unistd.h> 
#def MAXFD 256 

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

另一種選擇是讓文件描述符在由Python創建的fork調用中關閉。你是不是能夠做到這一點,如果你打電話os.system(),但如果你做與subprocess模塊幾乎等於叫你有這個選項:

from subprocess import Popen 

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

此。 Popen工作。 – Illiax