Не работает многопоточнось в Python
Не работает многопоточность в пайтон 3. Использую threading. Всё выполняется поочерёдно, хотя должно одновременно вот код
def start_threads(threads):
errors = 0
for i in range(3):
p = threading.Thread(target=Thread_Starter)
threads_list.append(p)
for i in threads_list:
i.setDaemon(True)
i.start()
Ответы (2 шт):
Проблема, которую решает GIL, связана с тем, что в многопоточном приложении сразу несколько потоков могут увеличивать или уменьшать значения счётчика ссылок. Это может привести к тому, что память очистится неправильно и удалится тот объект, на который ещё существует ссылка.
Счётчик ссылок можно защитить, добавив блокираторы на все структуры данных, которые распространяются по нескольким потокам. В таком случае счётчик будет изменяться исключительно последовательно.
Но добавление блокировки к нескольким объектам может привести к появлению другой проблемы — взаимоблокировки (англ. deadlocks), которая получается только если блокировка есть более чем на одном объекте. К тому же эта проблема тоже снижала бы производительность из-за многократной установки блокираторов.
GIL — эта одиночный блокиратор самого интерпретатора Python. Он добавляет правило: любое выполнение байткода в Python требует блокировки интерпретатора. В таком случае можно исключить взаимоблокировку, т. к. GIL будет единственной блокировкой в приложении. К тому же его влияние на производительность процессора совсем не критично. Однако стоит помнить, что GIL уверенно делает любую программу однопоточной.
Если вам нужно реальное параллельное исполнение кода используйте многопроцессность например с помощью модуля multiprocessing.
import random
import time
from threading import Thread
class MyThread(Thread):
def __init__(self, name):
Thread.__init__(self)
self.name = name
def run(self):
amount = random.randint(3, 15)
time.sleep(amount)
msg = "%s is running" % self.name
print(msg)
def create_threads():
for i in range(5):
name = "Thread #%s" % (i+1)
my_thread = MyThread(name)
my_thread.start()
if __name__ == "__main__":
create_threads()
С использованием multiprocessing:
from multiprocessing import Process, Lock
def printer(item, lock):
lock.acquire()
try:
print("Thread #%s" % item)
finally:
lock.release()
if __name__ == '__main__':
lock = Lock()
items = [1, 2, 3, 4, 5]
for item in items:
p = Process(target=printer, args=(item, lock))
p.start()