像这样将上下文注入 eventlet 线程安全吗?
Is it safe to inject context into a eventlet thread like this?
我需要注入线程级上下文信息以进行日志记录和调试。有人告诉我这可能不安全。
greenthread = worker_pool.spawn(run_worker, args, handle_result)
# this logging_context attribute will be accessed by the logging library
greenthread.__dict__['logging_context'] = 'data for logging'
greenthread.link()
虽然这肯定不是您经常想要做的事情,但这是我可以设置线程本地全局常量的唯一方法,记录器可以访问它。
稍后记录器可以通过
访问它
eventlet.getcurrent().logging_context
据我对 python 的了解,我不明白这有什么不安全的地方,为什么其他人说这可能会导致灾难?
虽然我认为它是一个相当丑陋的猴子补丁,但我并不是在创建全局可变状态。我正在创建一个线程局部常量,该常量在线程甚至 运行.
之前实例化
我同意,"safe/unsafe" 是为了痴迷 parents。作为程序员,我们可以以更严格和有用的方式定义对问题的预期。
- 这种方法现在有效,所以当 eventlet 和 greenlet 版本被锁定时,它会起作用并且一切都很好。
- 您将在
spawn
之后更改 Greenthread 属性。现在在新生成的 greenthread 执行之前需要 sleep()
或其他方式屈服于 "event loop",但这种行为将来可能会改变。这意味着 run_worker
可能已经 运行ning。在允许它们 运行. 之前,您可以使用 eventlet.pools.Pool()
来管理正确的设置和 link greenthreads
- 将来它可能会中断,因为 greenthread 会
__slots__
以节省内存,或者出于其他原因的特定 __setattr__
实现。
- 您正在做的事情已经过测试和支持 API,它被称为线程本地存储。您可以像常规 Python threadlocal object 一样使用它,但使用
threading
[1]. 的补丁版本
- 你可能更喜欢 Logbook[2],它有更简洁的方法来做同样的事情(在后台使用 threadlocal)。
threadlocal
路线的示例代码:
def add_logging_context(context, fun, *a, **kw):
tl = threading.local()
tl.logging_context = context
return fun(*a, **kw)
pool.spawn(add_logging_context, 'data for logging', run_worker, args, handle_result)
我需要注入线程级上下文信息以进行日志记录和调试。有人告诉我这可能不安全。
greenthread = worker_pool.spawn(run_worker, args, handle_result)
# this logging_context attribute will be accessed by the logging library
greenthread.__dict__['logging_context'] = 'data for logging'
greenthread.link()
虽然这肯定不是您经常想要做的事情,但这是我可以设置线程本地全局常量的唯一方法,记录器可以访问它。
稍后记录器可以通过
访问它eventlet.getcurrent().logging_context
据我对 python 的了解,我不明白这有什么不安全的地方,为什么其他人说这可能会导致灾难?
虽然我认为它是一个相当丑陋的猴子补丁,但我并不是在创建全局可变状态。我正在创建一个线程局部常量,该常量在线程甚至 运行.
之前实例化我同意,"safe/unsafe" 是为了痴迷 parents。作为程序员,我们可以以更严格和有用的方式定义对问题的预期。
- 这种方法现在有效,所以当 eventlet 和 greenlet 版本被锁定时,它会起作用并且一切都很好。
- 您将在
spawn
之后更改 Greenthread 属性。现在在新生成的 greenthread 执行之前需要sleep()
或其他方式屈服于 "event loop",但这种行为将来可能会改变。这意味着run_worker
可能已经 运行ning。在允许它们 运行. 之前,您可以使用 - 将来它可能会中断,因为 greenthread 会
__slots__
以节省内存,或者出于其他原因的特定__setattr__
实现。 - 您正在做的事情已经过测试和支持 API,它被称为线程本地存储。您可以像常规 Python threadlocal object 一样使用它,但使用
threading
[1]. 的补丁版本
- 你可能更喜欢 Logbook[2],它有更简洁的方法来做同样的事情(在后台使用 threadlocal)。
eventlet.pools.Pool()
来管理正确的设置和 link greenthreads
threadlocal
路线的示例代码:
def add_logging_context(context, fun, *a, **kw):
tl = threading.local()
tl.logging_context = context
return fun(*a, **kw)
pool.spawn(add_logging_context, 'data for logging', run_worker, args, handle_result)