如何在python的多线程环境中指定一部分代码在特定线程中运行?

Posted

技术标签:

【中文标题】如何在python的多线程环境中指定一部分代码在特定线程中运行?【英文标题】:How to specify a part of code to run in a particular thread in a multithreaded environment in python? 【发布时间】:2021-10-07 12:47:12 【问题描述】:

如何实现:

def call_me():
   # doing some stuff which requires distributed locking

def i_am_calling():
   # other logic
   call_me()
   # other logic

此代码在多线程环境中运行。我怎样才能做到这一点,只有线程池中的一个线程负责运行call_me()i_am_calling() 部分?

【问题讨论】:

你读过Lock和Semaphore吗?在页面末尾,您还可以看到使用 with 的示例 根据调用它的线程的身份编写行为不同的代码似乎是个坏主意。根据调用它的线程池工作者的身份编写行为不同的代码似乎是一个壮观的坏主意。你想这样做的原因是什么? (或者,我完全误解了你想要做什么?) @SolomonSlow call_me() 任务需要一个分布式锁(这里使用redis),并且这个函数每隔1小时安排一次。所以我不希望所有线程都在 1 小时后尝试获取锁。只有一个线程在做这个预定的工作。 我对 Python 的库了解不多,但我使用过的线程池通常不保证任何关于其工作线程的身份。特别是,一些线程池实现会在需求低的时间间隔内杀死工作线程,并在需求增加时创建新的工作线程。同样,我对 Python 中可用的功能了解不多,但是如果我正在编写一个需要每小时执行一次的程序,我会为此使用某种计时器任务,或者——最坏的情况——循环的专用线程,做这件事,然后睡一个小时。 我会处理你最坏的情况:一个循环的专用线程,做这件事,然后睡一个小时。对性能有好处吗? 【参考方案1】:

这取决于手头的确切要求和系统架构/解决方案。因此,其中一种方法可以基于lock,以确保一次只有一个进程进行锁定。

您可以通过尝试使用多处理模块的apply_async 来达到逻辑,该模块可以使用 pool.apply_async 调用许多不同的函数(不是同一类型的函数)。当该函数只被调用一次时,它应该只使用一个进程,但是您可以提前捆绑任务并将这些任务传递/提交给各个工作进程。还有 pool.apply 将任务提交到 pool ,但它会阻塞,直到函数完成或结果可用。它的等价物是基于 get() 的 pool.apply_async(func, args, kwargs).get() 或带有 pool.apply_async 而没有 get() 的回调函数。另外,需要注意的是 pool.apply(f, args) 确保池中只有一个 worker 会执行 f(args)。

您还可以通过尝试使用executor.submit 在其自己的线程中进行相应的调用来达到逻辑,concurrent.futures 是标准 Python 库的一部分。 asyncio 可以与 concurrent.futures 耦合,这样它就可以等待在此 example 中突出显示的 concurrent.futures 提供的线程或进程池中执行的函数。

如果您想定期运行例程功能,则可以根据threading.timer 实现逻辑。

【讨论】:

以上是关于如何在python的多线程环境中指定一部分代码在特定线程中运行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 python 中指定 zip 文件的压缩级别?

如何通过 terraform 在 ecs 任务定义中指定环境变量?

Ubuntu18.0 解决python虚拟环境中不同用户下或者python多版本环境中指定虚拟环境的使用问题

如何在 Xcode 4 中指定命令行参数?

如何在 .NET 中指定控制台应用程序的退出代码?

删除List中指定的元素