J'ai beaucoup de difficulté à comprendre le fonctionnement de la file d'attente de multitraitement sur python et comment l'implémenter. Disons que j'ai deux python modules d'accès Pour les données d'un fichier partagé, appelons ces deux modules un rédacteur et un lecteur. Mon plan est de faire en sorte que le lecteur et le rédacteur placent les demandes dans deux files d'attente de multitraitement distinctes, puis qu'un troisième processus mette ces demandes en boucle et les exécute en tant que tel.
Mon problème principal est que je ne sais vraiment pas comment implémenter correctement multiprocessing.queue, vous ne pouvez pas vraiment instancier l'objet pour chaque processus car il s'agira de files d'attente séparées, comment vous assurer que tous les processus sont liés à une file d'attente partagée (ou dans ce cas, les files d'attente)
Mon problème principal est que je ne sais vraiment pas comment implémenter correctement multiprocessing.queue, vous ne pouvez pas vraiment instancier l'objet pour chaque processus car il s'agira de files d'attente séparées, comment vous assurer que tous les processus sont liés à une file d'attente partagée (ou dans ce cas, les files d'attente)
Voici un exemple simple de lecteur et d’écrivain partageant une seule file d’attente ... L’écrivain envoie au lecteur une série d’entiers; lorsque l'écrivain est à court de chiffres, il envoie "DONE", ce qui permet au lecteur de sortir de la boucle de lecture.
from multiprocessing import Process, Queue
import time
import sys
def reader_proc(queue):
## Read from the queue; this will be spawned as a separate Process
while True:
msg = queue.get() # Read from the queue and do nothing
if (msg == 'DONE'):
break
def writer(count, queue):
## Write to the queue
for ii in range(0, count):
queue.put(ii) # Write 'count' numbers into the queue
queue.put('DONE')
if __name__=='__main__':
pqueue = Queue() # writer() writes to pqueue from _this_ process
for count in [10**4, 10**5, 10**6]:
### reader_proc() reads from pqueue as a separate process
reader_p = Process(target=reader_proc, args=((pqueue),))
reader_p.daemon = True
reader_p.start() # Launch reader_proc() as a separate python process
_start = time.time()
writer(count, pqueue) # Send a lot of stuff to reader()
reader_p.join() # Wait for the reader to finish
print("Sending {0} numbers to Queue() took {1} seconds".format(count,
(time.time() - _start)))
dans "from queue import Queue
"il n’existe pas de module appelé queue
, mais plutôt multiprocessing
. Par conséquent, il devrait ressembler à" from multiprocessing import Queue
"
Voici une utilisation simple morte de multiprocessing.Queue
et multiprocessing.Process
qui permet aux appelants d'envoyer un "événement" et des arguments à un processus séparé qui envoie l'événement à une méthode "do_" du processus. (Python 3.4+)
import multiprocessing as mp
import collections
Msg = collections.namedtuple('Msg', ['event', 'args'])
class BaseProcess(mp.Process):
"""A process backed by an internal queue for simple one-way message passing.
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.queue = mp.Queue()
def send(self, event, *args):
"""Puts the event and args as a `Msg` on the queue
"""
msg = Msg(event, args)
self.queue.put(msg)
def dispatch(self, msg):
event, args = msg
handler = getattr(self, "do_%s" % event, None)
if not handler:
raise NotImplementedError("Process has no handler for [%s]" % event)
handler(*args)
def run(self):
while True:
msg = self.queue.get()
self.dispatch(msg)
Usage:
class MyProcess(BaseProcess):
def do_helloworld(self, arg1, arg2):
print(arg1, arg2)
if __== "__main__":
process = MyProcess()
process.start()
process.send('helloworld', 'hello', 'world')
Le send
se produit dans le processus parent, le do_*
se produit dans le processus enfant.
J'ai laissé de côté toute gestion des exceptions qui interromprait évidemment la boucle d'exécution et quittait le processus enfant. Vous pouvez également le personnaliser en remplaçant run
pour contrôler le blocage ou autre chose.
Cela n’est vraiment utile que dans les cas où vous n’avez qu’un seul processus de travail, mais j’estime que c’est une réponse pertinente à cette question pour illustrer un scénario courant avec un peu plus d’orientation objet.