Python RabbitMQ 连接由 child 继承

Python RabbitMQ connection inherited by child

问题如下。 调用一个做两件事的 python 程序:连接到 rabbitmq 服务器并调用生成两个进程的 c 程序。

当python程序完成后,仍然建立连接负责child。

因此 child 在 parent 死亡时继承其 parent 资源。

正在做 netstat -putan | grep rabbitmqip

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

这是 python 脚本完成后我得到的。

我想在这种情况下连接会丢失。

这似乎发生在与 RabbitMQ 服务器的连接上,我们无法通过常规 TCP 连接重现。

以前有人遇到过这个问题吗?有什么解决方法吗?

python 代码将是我的兔子消费者,而 c 程序将是后台脚本,根据工人的工作产生或杀死。当我杀死消费者时,我无法建立连接,无论 spawn 是否处于活动状态,因为那样 children 会从队列中获取他们不理解的消息。

代码示例:

Python :

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

Child 程序。

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

当您在 unix 中通过 fork() 生成子进程时,child 进程继承所有 parent 的打开文件描述符。 child 进程负责关闭不需要的描述符。

您的代码两次调用 fork,一次是通过 os.system() 间接调用,然后是直接在您的 C 代码中调用。所以你有两种处理方法:

首先是关闭所有在 C 代码的 child 进程中不需要的未使用的文件描述符。这通常是一个很好的做法,如果您不这样做,如果您生成许多 children 并且它们都获得其 parent的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()