Python线程自调用线程意外行为
我正在测试一种并行运行多个任务的方法。这些任务将在并行线程中运行,我希望任务重复,直到设置了全局变量。我首先尝试启动并行线程,并确保它们能够正常工作。到目前为止,我所拥有的:Python线程自调用线程意外行为,python,python-3.x,multithreading,python-multithreading,Python,Python 3.x,Multithreading,Python Multithreading,我正在测试一种并行运行多个任务的方法。这些任务将在并行线程中运行,我希望任务重复,直到设置了全局变量。我首先尝试启动并行线程,并确保它们能够正常工作。到目前为止,我所拥有的: import threading from IPython.display import clear_output import time i = 0 j = 0 def main(): global i global j t1 = threading.Thread(name = "task1",
import threading
from IPython.display import clear_output
import time
i = 0
j = 0
def main():
global i
global j
t1 = threading.Thread(name = "task1", target = task1)
t2 = threading.Thread(name = "task2", target = task2)
t1.start()
t2.start()
def task1():
global i
i += 1
time.sleep(10)
t1 = threading.Thread(name = "task1", target = task1)
t1.start()
def task2():
global j
j -= 1
time.sleep(10)
t2 = threading.Thread(name = "task2", target = task2)
t2.start()
tmain = threading.Thread(name = "main", target = main)
tmain.start()
它启动一个主线程,然后启动运行task1和task2的两个线程。要监视当前线程以及i和j i run的值,请执行以下操作:
while(True):
clear_output(wait=True)
for thread in threading.enumerate():
print(thread)
print(i)
print(j)
time.sleep(0.1)
(所有这些都在Jupyter笔记本中运行)
运行上面的脚本时,我注意到一些意想不到的结果。我希望在任何给定的时间,task1和task2最多应该有两个线程,但与task1相比,我观察到task2的线程要多得多。这些不是重影线程或成品线程,因为i和j的绝对值增长不成比例。我提出了两项意见:
同样,我希望task1和Task2的线程数应该是对称的,并且我还希望i和j的abslute值应该比它们的增长更成比例。任何关于如何缓解这种差异或避免这种问题的见解都将不胜感激。我在Jupyter中运行了您的代码,没有您的问题
<_MainThread(MainThread, started 139735228168000)>
<Thread(Thread-1, started daemon 139735083251456)>
<Heartbeat(Thread-2, started daemon 139735074858752)>
<HistorySavingThread(IPythonHistorySavingThread, started 139735049680640)>
<Thread(task2, started 139734638634752)>
<Thread(task1, started 139734680598272)>
<Thread(task2, started 139735041287936)>
<Thread(task1, started 139734076618496)>
<Thread(task1, started 139735032895232)>
<Thread(task2, started 139734672205568)>
<Thread(task1, started 139734655420160)>
<Thread(task2, started 139734630242048)>
272
-272
272
-272
但正如您在自己的代码中看到的,每个任务都有多个实例在运行。因此,在一项任务“重新开始”后,它需要一段时间才能自杀
解决Jupyter问题的一个方法是让main函数控制重启已终止的任务。这确保每个任务始终只有一个线程在运行
import threading
from IPython.display import clear_output
import time
i = 0
j = 0
main_stop = False
def task1():
global i
i += 1
time.sleep(4)
def task2():
global j
j -= 1
time.sleep(4)
def main():
global i
global j
t1 = threading.Thread(name="task1", target=task1)
t2 = threading.Thread(name="task2", target=task2)
t1.start()
t2.start()
while not main_stop:
if not t1.is_alive():
del t1
t1 = threading.Thread(name="task1", target=task1)
t1.start()
if not t2.is_alive():
del t2
t2 = threading.Thread(name="task2", target=task2)
t2.start()
# wait for tasks to complete
while t1.is_alive():
time.sleep(0.1)
while t2.is_alive():
time.sleep(0.1)
tmain = threading.Thread(name="main", target=main)
tmain.start()
run_time = 30 # seconds
end_time = time.time() + run_time
while time.time() < end_time:
clear_output(wait=True)
for thread in threading.enumerate():
print(thread)
print(i)
print(j)
time.sleep(0.1)
main_stop = True
# wait for main to complete
while tmain.is_alive():
time.sleep(0.1)
print('program completed')
导入线程
从IPython.display导入清除输出
导入时间
i=0
j=0
主停止=错误
def task1():
全球i
i+=1
时间。睡眠(4)
def task2():
全球j
j-=1
时间。睡眠(4)
def main():
全球i
全球j
t1=threading.Thread(name=“task1”,target=task1)
t2=线程。线程(name=“task2”,target=task2)
t1.start()
t2.start()
虽然不是主停止:
如果不是t1,则表示_是否处于活动状态():
德尔t1
t1=threading.Thread(name=“task1”,target=task1)
t1.start()
如果不是t2,那么_是否还活着():
德尔t2
t2=线程。线程(name=“task2”,target=task2)
t2.start()
#等待任务完成
当t1.u还活着时()
睡眠时间(0.1)
当t2.还活着时()
睡眠时间(0.1)
tmain=threading.Thread(name=“main”,target=main)
tmain.start()
运行时间=30秒
结束时间=time.time()+运行时间
while time.time()
我将发布的代码复制到一个test.py
文件中,并从命令行(python3./test.py
)运行它,然后从IPython.display导入clear\u输出和clear\u输出(wait=True)
行注释掉,它会按照您的预期运行(图中只显示了两个线程,打印的值彼此大致相等,并且每5秒增加一次)。也许是Jupyter环境的某些因素让act变得有趣。试过这个,Jupyter似乎确实存在问题。