проблема производителя/потребителя с многопроцессорной обработкой Python

В предыдущих ответах использовалось форматирование%, которое постепенно прекращается в Python 3.0+. Предполагая, что вы используете Python 2.6+, здесь описана более перспективная система форматирования:

http://docs.python.org/library/string.html#formatstrings

Хотя есть и более продвинутые функции, простейшая форма выглядит очень близко к тому, что вы написали:

>>> "[{0}, {1}, {2}]".format(1, 2, 3)
[1, 2, 3]

14
задан btw0 28 May 2009 в 14:04
поделиться

2 ответа

Я думаю, что что-то не так с частью веб-сервера, так как это работает отлично:

from multiprocessing import Process, Queue, cpu_count
import random
import time


def serve(queue):
    works = ["task_1", "task_2"]
    while True:
        time.sleep(0.01)
        queue.put(random.choice(works))


def work(id, queue):
    while True:
        task = queue.get()
        if task is None:
            break
        time.sleep(0.05)
        print "%d task:" % id, task
    queue.put(None)


class Manager:
    def __init__(self):
        self.queue = Queue()
        self.NUMBER_OF_PROCESSES = cpu_count()

    def start(self):
        print "starting %d workers" % self.NUMBER_OF_PROCESSES
        self.workers = [Process(target=work, args=(i, self.queue,))
                        for i in xrange(self.NUMBER_OF_PROCESSES)]
        for w in self.workers:
            w.start()

        serve(self.queue)

    def stop(self):
        self.queue.put(None)
        for i in range(self.NUMBER_OF_PROCESS):
            self.workers[i].join()
        self.queue.close()


Manager().start()

Пример вывода:

starting 2 workers
0 task: task_1
1 task: task_2
0 task: task_2
1 task: task_1
0 task: task_1
11
ответ дан 1 December 2019 в 13:59
поделиться

«Второй вопрос, как лучше всего правильно остановить HTTP-сервер?»

Это сложно.

У вас есть два варианта для межпроцессного взаимодействия:

  • Out-of -полосное управление. У сервера есть другой механизм связи. Другой сокет, сигнал Unix или что-то еще. Что-то еще может быть файлом «остановить сейчас» в локальном каталоге сервера. Кажется странным, но он работает хорошо и проще, чем введение цикла select для прослушивания нескольких сокетов или обработчика сигнала для перехвата сигнала Unis.

    Файл «stop-now» легко реализовать. Цикл evwsgi.run () просто проверяет наличие этого файла после каждого запроса. Чтобы остановить сервер, вы создаете файл, выполняете запрос / control (который приведет к ошибке 500 или что-то в этом роде, это не так. t действительно важно), и сервер должен остановиться. Не забудьте удалить файл остановки сейчас, иначе ваш сервер не перезагрузится.

  • Внутриполосное управление. У сервера есть другой URL ( / stop ), который остановит его. На первый взгляд это похоже на кошмар безопасности, но это полностью зависит от того, где и как будет использоваться этот сервер. Поскольку кажется, что это простая оболочка для внутренней очереди запросов, этот дополнительный URL-адрес работает хорошо.

    Чтобы это работало, вам необходимо написать свою собственную версию evwsgi.run () , которая может быть завершается установкой некоторой переменной таким образом, чтобы выходить из цикла.

Edit

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

Если вы хотите принудительно убить сервер, тогда os.kill () (или multiprocessing. terminate ) будет работать. За исключением, конечно, того, что вы не знаете, что делали дочерние потоки.

4
ответ дан 1 December 2019 в 13:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: