Python multiprocessing.Process使用virtualenv

时间:2017-10-27 15:31:22

标签: python virtualenv python-multiprocessing

我正在使用virtualenv运行程序。但是这里产生的multiprocessing.Process默认使用系统python。如何强制它使用virtualenv python。

import os
from multiprocessing import Process

def function1():
    # do_something_here
    p = Process(func2(), args=(param,))
    p.start()
    return something

def func2(param):
    os.system("which python")

这里打印“/ usr / bin / python”。但是我需要它来使用virtualenv python。

2 个答案:

答案 0 :(得分:2)

使用sudo venv/bin/python,您{(3}}直接在virtualenv中使用python可执行文件。

multiprocessing.Process使用fork()生成子进程,没有exec(),它使用与父进程完全相同的python可执行文件。

您可以通过以下方式确认正在使用的python可执行文件:

>>> import sys
>>> print(sys.executable)
/Users/georgexsh/workspace/tmp/venv/bin/python
>>> print(sys.exec_prefix)
/Users/georgexsh/workspace/tmp/venv/bin/..

不要使用which来确定正在运行的python可执行路径。 which,作为Bash命令,搜索$PATH的每个元素,查找包含名为" python"的可执行文件的目录,因为您直接使用virtualenv' s python,而不是首先运行shell激活脚本,$PATH不能使用virtualenv修补,因此,shell命令which python将输出系统python可执行文件的路径。

实际上,在python层,$PATH是无关紧要的,修补$PATH是为了方便Bash层,只需键入" python&#即可在virtualenv路径中调用python可执行文件34;而不是键入完整路径,最重要的是调用哪个python可执行文件,而不是如何调用它。

答案 1 :(得分:1)

您的问题在这里(复制您的评论):

  

@georgexsh我是用sudo运行它的。默认情况下,如果您使用sudo   那么它将使用系统python。所以,我使用了" sudo venv / bin / python   main.py"运行程序。即使我在这里使用venv's python   它返回" / usr / bin / python" for" os.system(' which python')"。我没有   了解这种行为

基本上,你在这里解释的是你的virtualenv不活跃的东西。

当您激活virtualenv (. venv/bin/activate)时,激活脚本将更改您的环境,以便您的PYTHONPATH正确,并且首先在虚拟env目录中搜索(并找到)Python可执行文件。这就是virtualenv的作用。

通过从virtualenv目录执行Python二进制文件,您的环境不会为虚拟环境设置,因此对Python的任何后续调用都使用您的默认路径 - 因为virtualenv不会覆盖它。

执行sudo时,会创建一个新的进程/ shell,它不会继承您的虚拟环境。您可以使用sudo -E来传递环境,但这取决于您的sudo。应该在每个环境中工作的防弹版本是执行一个shell,它首先激活virtualenv,然后执行你的脚本。像这样:

sudo -- bash  -c ". /home/test/mytest/bin/activate; which python"

以root身份执行bash shell,然后激活虚拟环境,最后告诉你它使用的是哪个python。只需使用您的虚拟环境路径修改上述命令,它甚至可以工作。

如果你的系统是共享的,请记住,从安全角度来看,允许常规用户这是一件非常可怕的事情。如果你为普通用户创建一个无密码的sudo来做这件事,它会给他们root权限,只需要很少的调整。如果它是您自己的系统,并且要求是root密码的知识,那么无关紧要。