Estoy escribiendo un programa de servidor con un productor y varios consumidores,
lo que me confunde es sólo la primera tarea del productor poner en la cola se pone
consumido, después de que las tareas en la cola de espera ya no se consumen, permanecen
en la cola para siempre.

from multiprocessing import Process, Queue, cpu_count
from http import httpserv
import time

def work(queue):
    while True:
        task = queue.get()
        if task is None:
            break
        time.sleep(5)
        print "task done:", task
    queue.put(None)

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

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

        httpserv(self.queue)

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

Manager().start()

El productor es un servidor HTTP que poner una tarea en la cola una vez que reciba
una solicitud del usuario. Parece que los consumidores procesos de
bloqueado cuando hay nuevas tareas en la cola, que es raro.

P. S. Otra de las dos preguntas no relacionadas con las anteriores, no estoy seguro de si
es mejor poner el servidor HTTP en su propio proceso distinto de los principales
proceso, si sí, ¿cómo puedo hacer que el proceso principal de mantener funcionando antes de que todos los
los niños los procesos de final. Segunda pregunta, ¿cuál es la mejor manera de detener la
Servidor HTTP con gracia?

Editar: añadir productor de código, que es una simple python wsgi servidor:

import fapws._evwsgi as evwsgi
from fapws import base

def httpserv(queue):
    evwsgi.start("0.0.0.0", 8080)
    evwsgi.set_base_module(base)

    def request_1(environ, start_response):
        start_response('200 OK', [('Content-Type','text/html')])
        queue.put('task_1')
        return ["request 1!"]

    def request_2(environ, start_response):
        start_response('200 OK', [('Content-Type','text/html')])
        queue.put('task_2')
        return ["request 2!!"]

    evwsgi.wsgi_cb(("/request_1", request_1))
    evwsgi.wsgi_cb(("/request_2", request_2))

    evwsgi.run()

OriginalEl autor btw0 | 2009-05-27

3 Comentarios

  1. 10

    Creo que debe haber algo mal con el servidor web a parte, ya que este funciona a la perfección:

    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()
            queue.close()
    
    
    Manager().start()

    Ejemplo de salida:

    starting 2 workers
    0 task: task_1
    1 task: task_2
    0 task: task_2
    1 task: task_1
    0 task: task_1
    Impresionante, Mientras que Si usted puede proporcionar un productor + multi-trabajador de ejemplo. Sería agradable.
    NOTA, que tienes que cambiar la última línea en la parada de queue.close() a self.queue.close() para hacer referencia a la derecha de la cola

    OriginalEl autor Luper Rouch

  2. 4

    “Segunda pregunta, ¿cuál es la mejor manera de detener el servidor HTTP correctamente?”

    Esto es difícil.

    Usted tiene dos opciones para la Comunicación Entre procesos:

    • Fuera de banda de los controles. El servidor dispone de otro mecanismo de comunicación. Otro socket de Unix de la Señal, o algo más. La cosa podría ser un “stop-ahora” archivo en el servidor del directorio local. Parece extraño, pero funciona bien y es más simple que la introducción de una selección del bucle para escuchar en varios sockets o un manejador de señal para coger un Unis de la señal.

      El “parar ahora” el archivo es fácil de implementar. El evwsgi.run() bucle simplemente busca este archivo después de cada petición. Para hacer que el servidor deje, de crear el archivo, ejecutar un /control solicitud, recibirá un error 500 o algo así, realmente no importa) y el servidor debe detenerse. Recuerde eliminar el stop-ahora archivo, de lo contrario el servidor no se reinicie.

    • En la banda de los controles. El servidor tiene otra URL (/stop) que va a parar. Superficialmente, esto parece una seguridad pesadilla, pero depende completamente de dónde y cómo se utilizará este servidor. Dado que parece ser un simple contenedor alrededor de una solicitud interna de la cola, este extra URL funciona bien.

      Para hacer este trabajo, usted necesita escribir su propia versión de evwsgi.run() que puede ser terminado por configurar algunas variables de una manera que va a salir del bucle.

    Editar

    Usted probablemente no quiere terminar su servidor, ya que no sé el estado de subprocesos de trabajo. Usted necesita para enviar una señal al servidor y, a continuación, sólo tienes que esperar hasta que termine las cosas normalmente.

    Si quieres a la fuerza matar el servidor, a continuación, os.kill() (o multiprocessing.terminate) va a trabajar. Excepto, por supuesto, usted no sabe lo que el niño hilos estaban haciendo.

    Acerca de cómo poner el servidor en su propio proceso, y el uso de multiprocesamiento.Proceso.terminar método para terminar el proceso? Esto parece más fácil.

    OriginalEl autor S.Lott

Dejar respuesta

Please enter your comment!
Please enter your name here