Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python线程自调用线程意外行为_Python_Python 3.x_Multithreading_Python Multithreading - Fatal编程技术网

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似乎确实存在问题。