由子

时间:2017-07-06 16:54:19

标签: python c rabbitmq fork pika

问题如下。 调用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);
}

1 个答案:

答案 0 :(得分:1)

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

您的代码正在调用fork两次,一次是通过os.system()间接调用,然后再直接在您的C代码中调用。所以你有两种方法可以解决这个问题:

首先是关闭C代码子进程中不需要的所有未使用的文件描述符。这通常是一种很好的做法,如果您在系统中产生文件描述符并不常见,如果您产生了许多孩子并且他们都获得了父母的fds的副本。< / p>

#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()
相关问题