【问题标题】:Python RabbitMQ connection inherited by child孩子继承的 Python RabbitMQ 连接
【发布时间】:2018-01-26 05:34:34
【问题描述】:

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

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

【问题讨论】:

    标签: python c rabbitmq fork pika


    【解决方案1】:

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

    您的代码调用了两次 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()
    

    【讨论】:

      猜你喜欢
      • 2017-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多