Посты с тэгом потоки


[Перевод] О структуре параллельных вычислений или доводы против оператора «Go»


Каждый язык, поддерживающий параллельные (конкурентные, асинхронные) вычисления, нуждается в способе запуска кода параллельно. Вот примеры из разных API:


go myfunc();                                // Golang

pthread_create(&thread_id, NULL, &myfunc);  /* C with POSIX threads */

spawn(modulename, myfuncname, [])           % Erlang

threading.Thread(target=myfunc).start()     # Python with threads

asyncio.create_task(myfunc())               # Python with asyncio

Есть много вариантов нотации и терминологии, но одна семантика — запустить myfunc параллельно основной программе и продолжить родительский поток выполнения (англ. "Control Flow")



Threading и KeyboardInterrupt.

Как организовать пул потоков? Допустим у меня есть 100 данных (пусть они находятся в каком-либо списке) и все их нужно переработать в 10 потоков. Стартуем 10 потоков, в каждый передаем по 1 данному, следим за потоками, как только один отработал, стартуем новый и так пока не кончатся данные… В общем, это не то, чтобы бред, но есть способ поудобней.

За всё время работы скрипта, стартует только 10 потоков, просто каждый из них, отработав со своим 1 данным, не дохнет, а берет из списка следующее 1 данное и делает с ним эту же работу:

# -*- coding: utf-8 -*-
import threading, Queue, time
import traceback

class Worker(threading.Thread):
    def __init__(self,queue):
        threading.Thread.__init__(self)
        self.__queue = queue

    def run(self):
        while True:

            try: item = self.__queue.get_nowait() # ждём данные
            except Queue.Empty: break # данные закончились, прекращаем работу

            try: self.work(item) # работа