Я хочу запустить несколько потоков в python после того, как я введу гимн с клавиатуры, и я получаю эту ошибку - Исключение в потоке Thread-4: - PullRequest
0 голосов
/ 14 февраля 2020

Я хочу запустить несколько потоков в 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()

1 Ответ

1 голос
/ 16 февраля 2020

Вы должны опубликовать весь след. Вот что я получаю во всех 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() будет возвращать одно и то же значение во всех потоках.

Кроме того, если вы начнете и присоединитесь к потоку в том же l oop, вы не получите никакого параллелизма. Запустите все потоки в одном l oop, затем соедините (дождитесь завершения) в другом l oop.

Вот решение, демонстрирующее параллелизм:

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

Последнее замечание: процесс может запускать только код Python в одном потоке за раз благодаря глобальному интерпретатору CPython реализация блокировки (GIL), поэтому модуль threading не сэкономит время на Python -интенсивной работе, но полезен, когда Python ожидает ввода-вывода или вызывает собственные модули C, которые выпускают GIL , Модуль multiprocessing можно использовать для создания нескольких процессов Python, которые не ограничены GIL, но имеют более длительное время инициализации процесса и аргументы передаются через межпроцессные методы.

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
...