Python子进程在多线程环境中的行为不一致

Python子进程在多线程环境中的行为不一致,python,multithreading,subprocess,popen,Python,Multithreading,Subprocess,Popen,我在线程中运行了以下代码..'“可执行文件”为每个输入“url”生成唯一的字符串输出: p = Popen(["executable", url], stdout=PIPE, stderr=PIPE, close_fds=True) output,error = p.communicate() print output 当对多个输入“URL”执行上述代码时,生成的子流程p的“输出”不一致。对于某些URL,子流程终止而不生成任何“输出”。我尝试为每个失败的“p”实例打印p.returncode(

我在线程中运行了以下代码..'“可执行文件”为每个输入“url”生成唯一的字符串输出:

p = Popen(["executable", url], stdout=PIPE, stderr=PIPE, close_fds=True)
output,error = p.communicate()
print output

当对多个输入“URL”执行上述代码时,生成的子流程p的“输出”不一致。对于某些URL,子流程终止而不生成任何“输出”。我尝试为每个失败的“p”实例打印p.returncode(失败的URL在多次运行中也不一致)并将'-11'作为返回代码,将'error'值作为空字符串。是否有人可以建议一种方法,以便在多线程环境中为每次运行获得一致的行为/输出?

-11
,因为返回代码可能意味着C程序不正常,例如。,您启动的子进程太多,导致C可执行文件中出现
SIGSERV
。您可以使用以下命令限制并发子进程的数量:

#/usr/bin/env python
从multiprocessing.dummy导入池#使用线程
从子流程导入Popen、PIPE
def get_url(url):
p=Popen([“可执行文件”,url],stdout=PIPE,stderr=PIPE,close\u fds=True)
输出,错误=p.communicate()
返回url,输出,错误,p.returncode
池=池(20)#限制并发子进程的数量
对于池中的url、输出、错误、返回代码。imap_无序(获取url、url):
打印(“%s%r%r%d”%(url、输出、错误、返回代码))
确保可执行文件可以并行运行,例如,它不使用某些共享资源。要进行测试,可以在shell中运行:

$ executable url1 & executable url2

请您详细解释一下“您启动了太多的子进程,这会导致C可执行文件中出现SIGSERV”,以及可能的解决方案,以避免出现这种情况

可能的问题:

  • “进程太多”
  • ->“系统或其他资源内存不足”
  • ->“触发C代码中隐藏或罕见的错误”
  • ->“非法内存访问”
  • ->SIGSERV
建议的上述解决方案是:

  • “限制并发进程数”
  • ->“系统中有足够的内存或其他资源”
  • ->“错误是隐藏的或罕见的”
  • ->无信号服务
简而言之,如果你的程序试图访问一个不应该访问的内存,它就会被这个信号杀死。以下是此类计划的一个示例:

/*有时尝试使用SIGSERV失败*/
#包括
#包括
#包括
内部主(空){
char*null_指针=null;
srand((无符号)时间(NULL));
如果(rand()
如果您使用上面的Python脚本运行它,那么它偶尔会返回
-11

此外,p.returncode不足以用于调试目的。是否有其他选项可以获取更多调试信息以找到根本原因


我不会完全排除Python方面,但问题很可能是C程序。您可以使用来查看错误来自调用堆栈中的何处。

返回代码-11似乎表明您的C程序有问题

通常,如果您试图使用多个线程,您应该确切地知道您正在调用的程序是如何实现的。如果没有,你会遇到,像这样奇怪和模糊的错误

如果您无法访问C可执行文件的源代码,则必须使用C编写自己的线程安全版本,或者我建议您将外部程序作为Python中的函数实现。然后您可以将其与
多处理
模块并行


Python非常擅长创建和分析JSON,重新实现C程序可能是一个很好的练习。

我们需要更多关于可执行文件和Python程序的信息。听起来好像它做错了什么。您确定它正确返回您发送的URL吗?您能直接在python中完成可执行文件的工作吗?然后可以使用多处理模块。@WilliamDenman:hi..可执行文件是一个“C”程序二进制文件,它在标准输出上为给定的输入“url”生成JSON字符串输出。。python代码的其余部分只是解析输出字符串。。如果您需要更多信息,请告诉我。@WilliamDenman我确信“C”可执行二进制文件工作正常,就像串行执行一样,为每个url生成的输出是一致的。我无法用python代码替换C可执行文件..“打印”不是线程安全的…如何“执行多个输入URL”。请把你如何做的整个代码。按照您在问题中的方式,p.communicate()将阻塞,直到进程完成,因此不会并行执行任何工作。我使用的是“使用队列的子进程+线程(手动池)解决方案”方法。。池大小=100。。请您详细解释一下“您启动的子进程太多,导致C可执行文件中出现
SIGSERV
”以及可能的解决方案。我尝试了上面的代码,并确认少数子进程返回-11。对于失败的情况,“output”和“error”打印空字符串<代码>打印(“%s%r%r%d”%(url、输出、错误、返回代码))
还有p.returncode不足以用于调试目的。是否有其他选项可以获取更多调试信息以找到根本原因?@SagarG:我已经从评论中为您的问题添加了答案。