在subprocess Python 2模块中,Popen可以获得env
。
似乎在Process模块中使用multiprocessing执行此操作的等效方法是在env
或args
中传递kwargs
字典,然后使用os.environ['FOO'] = value
中的target
。
这是正确的方法吗?
安全吗?我的意思是,没有风险可以修改父进程或其他子进程中的环境吗?
这是一个例子(有效)。
import multiprocessing
import time
import os
def target(someid):
os.environ['FOO'] = "foo%i" % someid
for i in range(10):
print "Job %i: " % someid, os.environ['FOO']
time.sleep(1)
if __name__ == '__main__':
processes = []
os.environ['FOO'] = 'foo'
for someid in range(3):
p = multiprocessing.Process(target=target, args=(someid,))
p.start()
processes.append(p)
for i in range(10):
print "Parent: ", os.environ['FOO']
time.sleep(1)
for p in processes:
p.join()
答案 0 :(得分:16)
是的,这是正确的方法。虽然孩子将从父母继承其初始环境,但孩子对os.environ
的后续更改不会影响父母,反之亦然:
import os
import multiprocessing
def myfunc(q):
print "child: " + os.environ['FOO']
os.environ['FOO'] = "child_set"
print "child new: " + os.environ['FOO']
q.put(None)
q.get()
print "child new2: " + os.environ['FOO']
if __name__ == "__main__":
os.environ['FOO'] = 'parent_set'
q = multiprocessing.Queue()
proc = multiprocessing.Process(target=myfunc, args=(q,))
proc.start()
q.get()
print "parent: " + os.environ['FOO']
os.environ['FOO'] = "parent_set_again"
q.put(None)
输出:
child start: parent_set
child after changing: child_set
parent after child changing: parent_set
child after parent changing: child_set
如果您需要将初始环境传递给孩子,您只需将其传递到args
或kwargs
列表中:
def myfunc(env=None):
time.sleep(3)
if env is not None:
os.environ = env
print os.environ['FOO']
if __name__ == "__main__":
child_env = os.environ.copy()
for i in range(3):
child_env['FOO'] = "foo%s" % (i,)
proc = multiprocessing.Process(target=myfunc, kwargs ={'env' : child_env})
proc.start()
输出:
foo0
foo1
foo2
请注意,如果您使用multiprocessing.Pool
,则可以使用initializer
/ initargs
关键字参数在每个流程开始时设置一次正确的环境游泳池:
def init(env):
os.environ = env
def myfunc():
print os.environ['FOO']
if __name__ == "__main__":
child_env = os.environ.copy()
child_env['FOO'] = "foo"
pool = multiprocessing.Pool(initializer=init, initargs=(child_env,))
pool.apply(myfunc,())
输出:
foo