在线程中调用 运行 以外的方法
Calling a method other than run in a thread
我正在学习 Python 中的线程,但我对自己编写的以下代码感到困惑。启动Heartbeat线程后,stuff
方法调用相对于run
方法如何工作?是否存在关于 i
的竞争条件,如果存在,我该如何防止?
我想知道这种类型的构造是否可以有效地用于与线程通信。我不明白它是如何工作的,但是,就 Heartbeat
class 中的方法调用而言 run
被激活。我假设 sleep
允许 stuff
执行,但我不知道为什么。我可能过于复杂化了并且遗漏了一些明显的东西;然而,我缺乏直觉令人不安。任何帮助或建议将不胜感激。
1 import threading
2 import time
3
4 class Heartbeat(threading.Thread):
5 def __init__(self, delay):
6 threading.Thread.__init__(self, daemon = True)
7 self.delay = delay
8 self.i = 0
9
10 def run(self):
11 while True:
12 print("i = {}".format(self.i))
13 time.sleep(self.delay)
14
15 def stuff(self, i):
16 self.i = i
17
18 if __name__ == "__main__":
19 hbThread = Heartbeat(3)
20 hbThread.start()
21
22 i = 0
23 while True:
24 time.sleep(1)
25 i += 1
26 hbThread.stuff(i)
并且输出:
i = 0
i = 2
i = 5
i = 8
i = 11
编辑:在我看来,由于某些原因,这个问题与建议的重复问题不同。这是一个简单得多的问题,有一个非常具体的观点,而另一个问题是关于一般多线程的广泛问题。答案非常有帮助,但我没有看到任何解释我的情况的内部工作原理,也没有解释从我所知的不同线程调用的其他方法。如果它在那里,它可能超出了初学者完全理解的范围;这个问题比较简单,也比较切中要害,所以我觉得有它的用处。
当您从 Thread
继承时,您的实例就像一个人,一只脚站在厨房,一只脚站在客厅。方法将在哪个线程中 运行 取决于您从哪个线程调用它。 run
将是新线程中的主函数,它在那里调用 运行s 的每个方法。如果您从父级调用 stuff
,它将在 MainThread 中调用 运行。由于GIL,一次只能有一个线程运行。默认情况下,Python 3 中的线程将保持 GIL(因此能够执行 Python 代码)最多 5 毫秒,或者在阻塞 I/O 时更早地放弃它(就像你的time.sleep
)。进程中的所有线程共享相同的内存,因此您可以从新线程和 MainThread 追加到实例,两者都可以访问数据。
我正在学习 Python 中的线程,但我对自己编写的以下代码感到困惑。启动Heartbeat线程后,stuff
方法调用相对于run
方法如何工作?是否存在关于 i
的竞争条件,如果存在,我该如何防止?
我想知道这种类型的构造是否可以有效地用于与线程通信。我不明白它是如何工作的,但是,就 Heartbeat
class 中的方法调用而言 run
被激活。我假设 sleep
允许 stuff
执行,但我不知道为什么。我可能过于复杂化了并且遗漏了一些明显的东西;然而,我缺乏直觉令人不安。任何帮助或建议将不胜感激。
1 import threading
2 import time
3
4 class Heartbeat(threading.Thread):
5 def __init__(self, delay):
6 threading.Thread.__init__(self, daemon = True)
7 self.delay = delay
8 self.i = 0
9
10 def run(self):
11 while True:
12 print("i = {}".format(self.i))
13 time.sleep(self.delay)
14
15 def stuff(self, i):
16 self.i = i
17
18 if __name__ == "__main__":
19 hbThread = Heartbeat(3)
20 hbThread.start()
21
22 i = 0
23 while True:
24 time.sleep(1)
25 i += 1
26 hbThread.stuff(i)
并且输出:
i = 0
i = 2
i = 5
i = 8
i = 11
编辑:在我看来,由于某些原因,这个问题与建议的重复问题不同。这是一个简单得多的问题,有一个非常具体的观点,而另一个问题是关于一般多线程的广泛问题。答案非常有帮助,但我没有看到任何解释我的情况的内部工作原理,也没有解释从我所知的不同线程调用的其他方法。如果它在那里,它可能超出了初学者完全理解的范围;这个问题比较简单,也比较切中要害,所以我觉得有它的用处。
当您从 Thread
继承时,您的实例就像一个人,一只脚站在厨房,一只脚站在客厅。方法将在哪个线程中 运行 取决于您从哪个线程调用它。 run
将是新线程中的主函数,它在那里调用 运行s 的每个方法。如果您从父级调用 stuff
,它将在 MainThread 中调用 运行。由于GIL,一次只能有一个线程运行。默认情况下,Python 3 中的线程将保持 GIL(因此能够执行 Python 代码)最多 5 毫秒,或者在阻塞 I/O 时更早地放弃它(就像你的time.sleep
)。进程中的所有线程共享相同的内存,因此您可以从新线程和 MainThread 追加到实例,两者都可以访问数据。