在python中“绑定”环境变量的安全方法是什么?

时间:2014-01-21 06:21:15

标签: python multithreading environment-variables

假设我们有一个库A女巫的行为取决于某些人的价值 环境变量。 A_CONFIG_PATH实际上。我的一些任务使用 每个任务都有不同A_CONFIG_PATH的库。我这样做了 的方式

import os
import A

def task(**kw):
    os.environ['A_CONFIG_PATH'] = '/home/me/current/task/config/path'
    A.do_some_stuff(kw)

这很好,直到所有任务同步处理。但现在我需要 此任务处理中的并发性。

所以我怎么能保证每个任务都不会腐蚀另一个任务 如果我在单独的线程/进程中运行每个任务,它自己的A_CONFIG_PATH 或类似的东西。

1 个答案:

答案 0 :(得分:3)

有几种方法可以解决这个问题:

  1. 在子进程中运行每个任务,而不是在不同线程中的一个进程中运行
  2. 更改任务以将A_CONFIG_PATH值作为参数,而不是从环境中读取(从env读取与依赖全局变量一样糟糕......)
  3. 使用threading.local对象,而不是将字符串分配给os.environ[A_CONFIG_VALUE],这允许每个线程都有自己的值。但是,您需要稍微更改读取值的部分。
  4. 使用threading.local的示例:

    #one time init
    os.environ['A_CONFIG_PATH'] = threading.local()
    
    # set the value    
    def task(**kw):
        os.environ['A_CONFIG_PATH'].value = '/home/me/current/task/config/path'
        A.do_some_stuff(kw)
    
    # read the value
    config_path = os.environ['A_CONFIG_PATH'].value
    

    编辑:既然您说使用os.getenv正在阅读env var,您可以将第三个解决方案与此hack结合使用,将os.getenv替换为您自己的:

    # one time init
    orig_getenv = os.getenv
    def getenv_hacked(key, default=None):
        if key == 'A_CONFIG_PATH':
           return orig_getenv(key, default).value
         else:
           return orig_getenv(key, default)
    os.getenv = getenv_hacked
    os.environ['A_CONFIG_PATH'] = threading.local()