2011-05-06 78 views

回答

1

你可以在第一个子进程中打印出来,并在Python中处理该字符串?

+0

是的,但有没有更漂亮的方式,以便我不必从env解析脚本? – user443850 2011-05-06 01:21:27

+0

嗯,我最终这样做了。看起来像最直接的方式来做到这一点... – user443850 2011-05-07 00:19:16

4

不幸的是,孩子的环境一旦退出就会蒸发掉,即使使用/proc filesystem on Unix专用文件/proc/[pid]/environ它也不会反映子进程所做的更改。

即使上述方法奏效,您也会遇到竞争状况:父母需要确定阅读环境的“正确时间”,理想的情况是在孩子修改环境后进行。要做到这一点,家长需要与孩子进行协调,只要你协调,你也可以明确沟通。

您需要通过套接字,管道,共享内存等方式在父节点和子节点之间传递状态。multiprocessing module可以使这一点更容易,让您通过队列或管道将数据从子节点传递给父节点。

更新下面是一个使用multiprocessing模块让与子进程父进程股票价值的速写,和子进程与整个队列相互通信。这使得它非常简单:

import os 
from multiprocessing import Process, Manager, Queue 

def worker1(d, q): 
    # receive value from worker2 
    msg = q.get() 
    d['value'] += 1 
    d['worker1'] = os.getpid(), msg 

def worker2(d, q): 
    # send value to worker1 
    q.put('hi from worker2') 
    d['value'] += 1 
    d['worker2'] = os.getpid() 

if __name__ == '__main__': 
    mgr = Manager() 
    d = mgr.dict() 
    q = Queue() 
    d['value'] = 1 
    p1 = Process(target=worker1, args=(d,q)) 
    p1.start() 
    p2 = Process(target=worker2, args=(d,q)) 
    p2.start() 
    p1.join() 
    p2.join() 
    print d 

结果:

{'worker1': (47395, 'hi from worker2'), 'worker2': 47396, 'value': 3} 
+0

嗨,我不需要交换父母和孩子之间的环境,但实际上是在子过程之间。 – user443850 2011-05-06 16:14:06

+0

试图获得流程环境的限制仍然适用。我已经用一个简单的草图更新了我的答案,使用多处理模块让两个孩子互相沟通,并与父母分享数据。希望能帮助到你。 – samplebias 2011-05-06 16:23:51

2

在Windows中,你可以使用SET命令得到你想要的东西,像这样:

import os, tempfile, subprocess 

def set_env(bat_file): 
    ''' Set current os.environ variables by sourcing an existing .bat file 
     Note that because of a bug with stdout=subprocess.PIPE in my environment 
     i use '>' to pipe out the output of 'set' into a text file, instead of 
     of using stdout. So you could simplify this a bit... 
    ''' 

    # Run the command and pipe to a tempfile 
    temp = tempfile.mktemp() 
    cmd = '%s && set > %s'%(bat_file,temp) 
    login = subprocess.Popen(cmd, shell=True) 
    state = login.wait() 

    # Parse the output 
    data = [] 
    if os.path.isfile(temp): 
     with open(temp,'r') as file: 
      data = file.readlines() 
     os.remove(temp) 

    # Every line will set an env variable 
    for env in data: 
     env = env.strip().split('=') 
     os.environ[env[0]] = env[1] 


# Make an environment variable 
os.environ['SOME_AWESOME_VARIABLE']='nothing' 

# Run a batch file which you expect, amongst other things, to change this env variable 
set_env('C:/do_something_awesome.bat') 

# Lets see what happened 
os.environ['SOME_AWESOME_VARIABLE'] 
// RESULT: 'AWESOME' 

所以现在如果您可以使用它来读取.bat文件,然后使用它生成的环境变量,请修改/添加它们,传递给新进程...等等。

4

这是一个简单的函数,它在子进程中运行一个命令,然后将其环境提取到当前进程中。

它基于Fnord的版本,没有tempfile,并且有一个标记行来区分SET命令和进程本身的任何输出。这不是防弹的,但它适用于我的目的。

def setenv(cmd): 
    cmd = cmd + ' && echo ~~~~START_ENVIRONMENT_HERE~~~~ && set' 

    env = (subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 
        .stdout 
        .read() 
        .decode('utf-8') 
        .splitlines()) 

    record = False 
    for e in env: 
     if record: 
      e = e.strip().split('=') 
      os.environ[e[0]] = e[1] 
     elif e.strip() == '~~~~START_ENVIRONMENT_HERE~~~~': 
      record = True 
相关问题