【问题标题】:Threads in Java and PythonJava 和 Python 中的线程
【发布时间】:2009-06-09 15:49:05
【问题描述】:

我对 Python 和 Java 中的线程有一些疑问......

  1. 是否可以像在 Java 中那样为 Python 线程指定优先级?
  2. 如何在 Python 中终止、停止、挂起和中断线程?
  3. 线程组 - 它们的真正用途是什么? Python 也支持它们吗?
  4. 同步 - 在 Java 中,我们对方法、对象使用简单的关键字 synchorinized...Python 呢?

Tnx!

【问题讨论】:

    标签: java python multithreading


    【解决方案1】:

    假设我们谈论的是经典 (CPython) 实现:

    1. 不,Python 线程中没有优先级
    2. 您不能对 Python 中的线程执行任何这些操作
    3. Python 中没有线程组
    4. 您可以使用多种方法,例如锁,但推荐的方法通常是使用标准库中的 Queue 模块(并将线程的交互限制在 Queue 允许您编程的范围内)

    换句话说,Python 线程实际上远没有 Java 丰富——更不用说每个进程实际上只有一个线程可以运行 Python 代码(其他线程可能正在运行 C 代码或等待)。

    对于任何花哨的东西,即超出 Python 有限线程功能的任何东西,建议您使用标准库中的 multiprocessing 模块 - 或切换到允许您使用更丰富的线程方法的 Python 实现,例如用于 JVM 的 Jython或 IronPython for .NET。

    【讨论】:

      【解决方案2】:

      不能指望常规的 java 线程优先级。当较高优先级的线程准备好并等待时,您可能会发现较低优先级的线程正在运行。

      有一种叫做“realtime java”的东西(参见http://www.rtsj.org)确实强制执行线程优先级,至少对于 RealtimeThread 类。常规的 java.lang.Thread 可能仍然无法强制执行真正的优先级排序。

      【讨论】:

        【解决方案3】:

        我觉得有必要揭穿这里长期存在的常见神话:

        是否可以像在 Java 中那样为 Python 线程分配优先级?

        不是操作系统意义上的。但是您可以使用协作多任务处理和您自己的自定义调度程序来确保某些线程使用更多时间。您还可以使用以下方法设置线程之间的时间片:

        http://docs.python.org/library/sys.html#sys.setcheckinterval

        如何在 Python 中杀死、停止、挂起和中断线程?

        请注意,您可以做到这一点。这很困难,人们会对它是多么的邪恶充满哲理。但这在任何语言中都是正确的。您可以使用以下 API 函数:

        http://docs.python.org/c-api/init.html#PyThreadState_SetAsyncExc

        或者您可以在关闭 TID 的窗口中使用您的底层操作系统,例如 TerminateThread。只要确保获得全局锁即可。

        线程组 - 它们的真正用途是什么? Python 也支持它们吗?

        我不相信。它们用于控制线程组。

        同步 - 在 Java 中,我们对方法、对象使用简单的关键字 synchorinized...Python 呢?

        读取线程和线程模块。

        【讨论】:

          【解决方案4】:

          这是我如何让我的线程暂停的示例(仅适用于循环内的线程,除非你想在每一行之前放置一个 if "self.alive"):

          import threading, Queue
          
          class HaltableThread(object.Thread):
              def __init__(self):
                  self.stringQueue = Queue.Queue()
                  self.alive = True
              def run(self):
                  while self.alive:
                      try:
                          data = self.stringQueue.read(0.01) #100ms block until data
                      except Queue.Empty:
                          pass
                      else:
                          print data
              def stop(self):
                  self.alive = False
          

          【讨论】:

            【解决方案5】:

            这里只是绕开第 1 点,因为 Java 线程优先级可能无法按预期工作。

            来自 SCJP 指南:

            由于无法保证线程调度优先级行为,因此请使用线程优先级作为提高程序效率的一种方式,但请确保您的程序不依赖该行为来确保正确性。

            【讨论】:

              【解决方案6】:

              不幸的是,标准的 Python 包有一个叫做 GIL 或全局解释器锁的东西。这意味着一次只有一个线程会运行。话虽如此,简单的多线程应用程序是可能的并且非常容易编写。线程模块包含基本的同步原语,如互斥体、信号量等。

              还有一个很棒的 with 语句可以自动执行锁使用的大部分方面。举个例子:

              import threading
              myLock = threading.Lock()
              

              然后使用锁:

              with myLock:
                  #lock has now been acquired
                  print "I have the lock and can now to fun stuff"
              print "The lock has been released"
              

              【讨论】:

              • GIL 并非不幸。有了它,代码运行得更快,所以这是一件好事。
              • @nosklo:实际上,如果你有一台多核机器,GIL 会使一些事情变慢。查看us.pycon.org/2010/conference/schedule/event/P82
              • @yarmiganosca:仅当您编写重线程代码并将 IO 与 CPU 密集型线程混合使用时,这不是常见的模式。对于大多数实际用例和几乎所有现实生活中的程序,GIL 都非常好并且可以提高速度。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-09-24
              • 1970-01-01
              • 1970-01-01
              • 2012-03-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多