首页 > 解决方案 > 从键盘输入东西后,我想在 python 中运行多个线程,但出现此错误-线程 Thread-4 中的异常:

问题描述

从键盘输入东西后,我想在 python 中运行多个线程,但出现此错误-线程 Thread-4 中的异常:

import threading
import os
import cv2

def task():
    user_input = input()
    print(user_input)
    print("Task assigned to thread: {}".format(threading.current_thread().name))
    print("ID of process running task : {}".format(os.getpid()))
    print("Thread started now")

if __name__ == "__main__":
    for i in range(1, 5):
         # Instantiates the thread
        t = threading.Thread(target=task, args=(i,))
        t.start()
        t.join()

标签: python-3.xmultithreadingpython-multithreading

解决方案


您应该发布整个回溯。这是我在所有 4 个线程中得到的:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python38\lib\threading.py", line 932, in _bootstrap_inner
    self.run()
  File "C:Python38\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
TypeError: task() takes 0 positional arguments but 1 was given

它说该函数task()在不需要任何参数时传递了一个参数,因此在创建线程时不要传递参数:

t = threading.Thread(target=task, args=())

或提出task()论点:

def task(i):

在线程中请求输入也没有任何意义。没有提示,您将不知道哪个线程正在接受输入。

由于使用threading而不是multiprocessing模块,os.getpid()因此将在所有线程中返回相同的值。

此外,如果您在同一个循环中启动并加入线程,则不会获得任何并行性。在一个循环中启动所有线程,然后在另一个循环中加入(等待完成)。

这是一个演示并行性的解决方案:

import threading
import os
import time

def task(i):
    print(f'Task#{i} started in {threading.current_thread().name}')
    time.sleep(5) # do some "work"
    print(f'Task#{i} done')

threads = [threading.Thread(target=task,args=(i,)) for i in range(1,5)]
print(f'Start: {time.ctime()}')
for t in threads:
    t.start()
for t in threads:
    t.join()
print(f'End:   {time.ctime()}')

输出(注意开始和结束时间相隔 5 秒):

Start: Sat Feb 15 16:22:59 2020
Task#1 started in Thread-1
Task#2 started in Thread-2
Task#3 started in Thread-3
Task#4 started in Thread-4
Task#1 done
Task#2 done
Task#4 done
Task#3 done
End:   Sat Feb 15 16:23:04 2020

最后一点:由于 CPython 的全局解释器锁 (GIL) 实现,一个进程一次只能在一个线程中运行 Python 代码,因此该threading模块不会为 Python 密集型工作节省时间,但在 Python 等待时很有用I/O 或调用释放 GIL 的本机 C 模块。该multiprocessing模块可用于创建不受 GIL 限制的多个 Python 进程,但具有更长的进程初始化时间,并且参数通过进程间方法传递。

import multiprocessing as mp
import os
import time

def task(i):
    print(f'Task#{i} started in {mp.current_process().name}')
    time.sleep(5)
    print(f'Task#{i} done')

if __name__ == '__main__':
    processes = [mp.Process(target=task,args=(i,)) for i in range(1,5)]
    print(f'Start: {time.ctime()}')
    for p in processes:
        p.start()
    for p in processes:
        p.join()
    print(f'End:   {time.ctime()}')

输出:

Start: Sat Feb 15 16:32:26 2020
Task#4 started in Process-4
Task#3 started in Process-3
Task#1 started in Process-1
Task#2 started in Process-2
Task#1 done
Task#4 done
Task#3 done
Task#2 done
End:   Sat Feb 15 16:32:31 2020

推荐阅读