【问题标题】:How do I thread these functions?如何线程化这些函数?
【发布时间】:2021-07-31 03:37:00
【问题描述】:

我正在尝试在 python 中编写一个警报,它有 6 个需要多线程的函数。其中5个是警报,其中一个显示时间。只要选择菜单选项以及警报响铃时,线程需要启动和停止。显示线程是唯一一直运行到程序停止的线程。我当前的警报代码如下所示(为了清楚起见,我删除了很多)

class TAlarm1 (threading.Thread):
    def Alarm1():
        while True:
            #code which keeps running until the time is equal to the input given (expected to thread)

                            
thread1 = threading.Thread(target=TAlarm1)
thread1.start()

            
def AlarmSelector():
    print("Select an Alarm") #5 alarms will be added however each one accomplishes the same task. all of them need to run simultaneously
    choice = int(input())
    if choice == 1:
        ala = TAlarm1()
        ala.Alarm1()
    if choice == 6:
        DisplayTime() #goes back to displaying time 
     

每当我运行此代码时,程序都不会显示任何错误,但它不会运行 TAlarm1() 中的代码。 我该如何解决这个问题?

【问题讨论】:

  • 你为什么要创建一个Thread 子类而不覆盖run 方法,然后将该类用作threading.Thread 的目标参数?那么你永远不会使用thread1。您的意图有点模糊,看起来您可能已经以please fix everything that is wrong with this 的形式提出了一些问题。

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


【解决方案1】:

在 Python 中实现线程代码有两种基本方法。你似乎各有一半。

第一个实现模型是将要在线程中运行的逻辑放入一个函数中,然后在创建threading.Thread 实例时将该函数作为target 参数传递:

import threading
import time

def worker(n):
    for i in range(n):
        print(i)
        time.sleep(0.5)

my_thread = threading.Thread(target=worker, args=(10,))
my_thread.start()

# do other stuff in the main thread, if desired

my_thread.join()

另一种实现方法是继承threading.Thread 并将要运行的代码放在run 方法内部的线程中(或从run 调用的其他方法中)。如果您的线程代码具有一些复杂的状态,并且您希望能够在线程运行时使用其他方法来操作该状态,这将特别有用:

class MyThread(threading.Thread):
    def __init__(self, n):
        super().__init__()
        self.n = n
        self.unpaused = threading.Event()
        self.unpaused.set() # we start unpaused

    def run(self):
        for i in range(self.n):
            self.unpaused.wait() # block if we're paused
            print(i)
            time.sleep(0.5)

    def pause(self):
        self.unpaused.clear()

    def unpause(self):
        self.unpaused.set()

my_thread = MyThread(10)
my_thread.start()

# an example of inter-thread communication, we pause and unpause our thread using its methods
time.sleep(2)
my_thread.pause()
time.sleep(2)
my_thread.unpause()

my_thread.join()

【讨论】:

    【解决方案2】:

    Threadtarget 参数采用可调用。类是可调用的,但调用它只会创建类的实例。改为传递一个 function

    import threading
    
    def Alarm1():
        print('Alarm1 called')
                                
    thread1 = threading.Thread(target=Alarm1)
    thread1.start()
    

    【讨论】:

      【解决方案3】:

      虽然我不清楚你的意图。以下是如何将 Thread 子类化并重写其 run 方法并有条件地启动它。

      import threading
      class TAlarm1 (threading.Thread):
          def run(self):
              n =4
              while True:
                  #code which keeps running until the time is equal to the input given (expected to thread)
                  print(n,end=' | ')
                  n -= 1
                  if n < 0:
                      break
              print()
      
      t1 = TAlarm1()
      if True:
          t1.start()
      

      一个线程只能启动一次,因此每次需要运行时都必须创建一个新线程。

      >>> t = TAlarm1() 
      >>> t.start()
      4 | 3 | 2 | 1 | 0 | 
      >>> t.start()
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "C:\Python38\lib\threading.py", line 848, in start
          raise RuntimeError("threads can only be started once")
      RuntimeError: threads can only be started once
      >>> t = TAlarm1()
      >>> t.start()
      4 | 3 | 2 | 1 | 0 | 
      >>>
      

      【讨论】:

        猜你喜欢
        • 2015-01-25
        • 2014-07-20
        • 2016-02-16
        • 2020-07-17
        • 2015-07-27
        • 2019-03-29
        • 2016-10-31
        • 1970-01-01
        • 2013-04-08
        相关资源
        最近更新 更多