python - 强制一个线程阻止所有其他线程执行

标签 python multithreading python-3.x python-multithreading

更新:

This answer声明说,截至 2013 年 4 月,我正在尝试做的事情是不可能的。然而,这似乎与 Alex Martelli 在 Python Cookbook 中所说的相矛盾。 (第 624 页,第 3 版):

Upon return, PyGILState_Ensure() always guarantees that the calling thread has exclusive access to the Python interpreter. This is true even if the calling C code is running a different thread that is unknown to the interpreter.



The docs似乎也建议可以获得 GIL,这会给我希望(除了我认为我不能从纯 python 代码中调用 PyGILState_Ensure(),如果我创建一个 C 扩展来调用它,我不知道如何将我的 memory_daemon() 嵌入其中)。

也许我误读了答案或 Python Cookbook 和文档。

原问题:

我想要一个给定的线程(来自 threading 模块)来防止任何其他线程在其代码的某个段正在执行时运行。实现它的最简单方法是什么?

显然,尽量减少其他线程中的代码更改,避免使用 C 和直接操作系统调用,并使其跨平台用于 windows 和 linux 会很棒。但实际上,我很乐意为我的实际环境提供任何解决方案(见下文)。

环境:
  • CPython
  • python 3.4(但如果有帮助,可以升级到 3.5)
  • Ubuntu 14.04

  • 用例:

    出于调试目的,我计算了所有对象使用的内存(由 gc.get_objects() 报告),并将一些摘要报告打印到 sys.stderr .我在一个单独的线程中执行此操作,因为我希望此摘要从其他线程异步传递;我把time.sleep(10)while True进行实际内存使用计算的循环。但是,内存报告线程需要一段时间才能完成每个报告,并且我不希望所有其他线程在内存计算完成之前进行(否则,内存快照将很难解释)。

    示例(澄清问题):
    import threading as th
    import time
    
    def report_memory_consumption():
      # go through `gc.get_objects()`, check their size and print a summary
      # takes ~5 min to run
    
    def memory_daemon():
      while True:
        # all other threads should not do anything until this call is complete
        report_memory_consumption()
        # sleep for 10 sec, then update memory summary
        # this sleep is the only time when other threads should be executed
        time.sleep(10)
    
    
    def f1():
      # do something, including calling many other functions
      # takes ~3 min to run
    
    def f2():
      # do something, including calling many other functions
      # takes ~3 min to run
    
    
    def main():
      t_mem = th.Thread(target = memory_daemon)
      t1 = th.Thread(target = f1)
      t2 = th.Thread(target = f2)
      t_mem.start()
      t1.start()
      t2.start()
    
    # requirement: no other thread is running while t_mem is not sleeping
    

    最佳答案

    您应该使用线程锁在线程之间同步执行代码。给出的答案有些正确,但我会使用可重入的本地人再次检查您是否确实拥有锁。

    不要使用另一个答案中描述的变量来检查是否拥有锁。变量可能会在多个线程之间损坏。重入锁就是为了解决这个问题。

    此外,该代码中的错误在于,假设两者之间的代码不引发异常,则锁定被释放。所以总是在 with上下文或 try-catch-finally .

    这是一个很棒的 article解释 Python 中的同步和线程 docs .

    编辑:回答 OP 关于在 C 中嵌入 Python 的更新

    你误解了他在食谱中所说的话。 PyGILState_Ensure如果 GIL 在 中可用,则返回 GIL当前的python解释器但不是python解释器未知的C线程。

    您不能强制从当前解释器中的其他线程获取 GIL。想象一下,如果您能够这样做,那么基本上您将蚕食所有其他线程。

    关于python - 强制一个线程阻止所有其他线程执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29317120/

    相关文章:

    python matplotlib.pyplot 和 numpy 问题

    python - 如何忽略 Python 中多输出函数的输出?

    c++ - 在多线程 C++11 程序中未处理异常时会发生什么?

    jquery - 如何在 Django 中创建多选框?

    python - pretty-print 数据类更漂亮

    python - 文本输入和服务器之间的接口(interface),用于使用该文本执行命令行应用程序

    ruby - 两个Ruby线程相关的问题

    c++ - 我应该使用静态工作池还是动态工作池(线程)?

    python - 获取下一个枚举器常量/属性

    用于在类中注册标签的 Python Decorator