Не работает многопоточнось в 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 шт):

Автор решения: Ildar

Проблема, которую решает GIL, связана с тем, что в многопоточном приложении сразу несколько потоков могут увеличивать или уменьшать значения счётчика ссылок. Это может привести к тому, что память очистится неправильно и удалится тот объект, на который ещё существует ссылка.

Счётчик ссылок можно защитить, добавив блокираторы на все структуры данных, которые распространяются по нескольким потокам. В таком случае счётчик будет изменяться исключительно последовательно.

Но добавление блокировки к нескольким объектам может привести к появлению другой проблемы — взаимоблокировки (англ. deadlocks), которая получается только если блокировка есть более чем на одном объекте. К тому же эта проблема тоже снижала бы производительность из-за многократной установки блокираторов.

GIL — эта одиночный блокиратор самого интерпретатора Python. Он добавляет правило: любое выполнение байткода в Python требует блокировки интерпретатора. В таком случае можно исключить взаимоблокировку, т. к. GIL будет единственной блокировкой в приложении. К тому же его влияние на производительность процессора совсем не критично. Однако стоит помнить, что GIL уверенно делает любую программу однопоточной.

источник

Если вам нужно реальное параллельное исполнение кода используйте многопроцессность например с помощью модуля multiprocessing.

→ Ссылка
Автор решения: Daniil Loban
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()
→ Ссылка