![](/img/trans.png)
[英]Python multiprocessing RemoteManager under a multiprocessing.Process
[英]Spawn multiprocessing.Process under different python executable with own path
我有兩個版本的Python(這些實際上是兩個conda環境)
/path/to/bin-1/python
/path/to/bin-2/python
從一個版本的python我想要使用類似multiprocessing.Process
對象的東西啟動在另一個版本中運行的函數。 事實證明,使用set_executable
方法是可行的:
ctx = multiprocess.get_context('spawn')
ctx.set_executable('/path/to/bin-2/python')
事實上,我們可以看到這實際上是使用該可執行文件啟動的:
def f(q):
import sys
q.put(sys.executable)
if __name__ == '__main__':
import multiprocessing
ctx = multiprocessing.get_context('spawn')
ctx.set_executable('/path/to/bin-2/python')
q = ctx.Queue()
proc = ctx.Process(target=f, args=(q,))
proc.start()
print(q.get())
$ python foo.py
/path/to/bin-2/python
但是,當我使用sys.path
而不是sys.executable
執行相同的操作時,我發現托管python進程的sys.path被打印出來,而不是我從運行/path/to/bin-2/python -c "import sys; print(sys.path)"
找到的sys.path /path/to/bin-2/python -c "import sys; print(sys.path)"
直接。
如果我使用fork,我習慣了這種事情。 我本來希望'spawn'
的行為與我從shell中輸入python解釋器一樣。
是否可以使用多處理庫來運行函數,並使用其他Python可執行文件中的隊列以及從shell啟動它時所具有的環境?
更廣泛地說,如何填充sys.path以及以這種方式使用多處理和直接啟動解釋器之間有什么不同?
我遇到了同樣的問題。 我的系統范圍的Python可執行文件位於/path/to/bin-1/python
,我使用virtualenv
在/path/to/bin-2/python
創建了一個包含另一個Python可執行文件的虛擬環境。 要為/path/to/bin-2/python
所需的生成進程設置正確的路徑/環境,我最終將virtualenv
文件夾中activate_this.py
的代碼復制到f(q)
。
def f(q):
import sys, os
def active_virtualenv(exec_path):
"""
copy virtualenv's activate_this.py
exec_path: the python.exe path from sys.executable
"""
# set env. var. PATH
old_os_path = os.environ.get('PATH', '')
os.environ['PATH'] = os.path.dirname(os.path.abspath(exec_path)) + os.pathsep + old_os_path
base = os.path.dirname(os.path.dirname(os.path.abspath(exec_path)))
# site-pachages path
if sys.platform == 'win32':
site_packages = os.path.join(base, 'Lib', 'site-packages')
else:
site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
# modify sys.path
prev_sys_path = list(sys.path)
import site
site.addsitedir(site_packages)
sys.real_prefix = sys.prefix
sys.prefix = base
# Move the added items to the front of the path:
new_sys_path = []
for item in list(sys.path):
if item not in prev_sys_path:
new_sys_path.append(item)
sys.path.remove(item)
sys.path[:0] = new_sys_path
return None
active_virtualenv(sys.executable)
q.put(sys.executable)
# check some unique package in this env.
import special_package
print "package version: {}".format(special_package.__version__)
if __name__ == '__main__':
import multiprocessing
multiprocessing.set_executable('/path/to/bin-2/python')
q = multiprocessing.Queue()
proc = multiprocessing.Process(target=f, args=(q,))
proc.start()
proc.join()
print(q.get())
stdouts:
$ python foo.py
/path/to/bin-2/python
package version: unique_version_only_in_virtualenv
我不太確定的一件事是sys
和os
是在active_virtualenv()
之前import
,這意味着它們來自系統范圍的Python環境。 但我在f(q)
中需要的其他包來自虛擬環境。 也許在切換env后重新import
它們是值得的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.