PROBLEM:

Es gibt zwei separate Prozesse, die parallel ablaufen, und ich möchte, dass sie hin und her kommunizieren.

ERKLÄRUNG DES CODES

Der Code ist in Python2.7. In meinem auf ein Minimum reduzierten Skript verwende ich eine Warteschlange für die Kommunikation zwischen Prozessen. Der Prozess p1 stellt Daten in eine Warteschlange. Der Prozess p2 holt die Daten aus der Warteschlange und macht etwas mit den Daten. Dann stellt der Prozess p2 die geänderten Daten wieder in die Warteschlange und schließlich erhält der Prozess p1 die geänderten Daten aus der Warteschlange zurück. Die geänderten Daten müssen zum Prozess p1 zurückkehren, da dieser Prozess tatsächlich ein Eventlet-Server ist, der Anforderungen sendet / empfängt.

CODE

#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
# script for back-and-forth data exchange between processes

# common modules
import os
import sys
import time
from multiprocessing import Process
from multiprocessing import Queue
from datetime import datetime

someData = {}

class Load():
    def post(self):
        timestamp = str(datetime.now())
        someData = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
        queue1.put(someData)        # put into queue
        print "#20 process 1: put in queue1 =>", someData
        time.sleep(3)

        while True:     # queue1 checking loop, comment out the loop if use time.sleep only
            if queue1.empty() == False:
                timestamp = str(datetime.now())
                res = queue1.get()
                res = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
                print "#28 get from queue1 =>", res
                break
            else:
                print "#31 queue1 empty"
                time.sleep(1)

        # while True:       # queue2 checking loop
        #   if queue2.empty() == False:
        #       timestamp = str(datetime.now())
        #       res = queue2.get()
        #       res = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
        #       print "#39 get from queue2 =>", res
        #       break
        #   else:
        #       print "#42 queue2 empty"
        #       time.sleep(1)

class Unload():
    def get(self):
        try:
            if queue1.empty() == False:
                data = queue1.get()     # retrieve package from queue
                #queue1.close()
                #queue1.join_thread()
                timestamp = str(datetime.now())
                data = {"process":"p2","class":"Unload()","method":"get()","timestamp":timestamp} 
                print "#54 process 2: get from queue1 =>", data
                self.doSomething(data)  # call method
            else:
                print "#57 queue1 empty"
                pass
        except:
            print "#60 queue1 error"
            pass

    def doSomething(self, data):
        time.sleep(3)
        timestamp = str(datetime.now())
        someData = {"process":"p2","class":"Unload()","method":"doSomething()","timestamp":timestamp}
        self.someData = someData
        print "#68 process 2: do something =>", someData
        self.put()

    def put(self):
        time.sleep(3)
        timestamp = str(datetime.now())
        self.someData = {"process":"p2","class":"Unload()","method":"put()","timestamp":timestamp}
        print "#75 process 2: put back in queue1 =>", self.someData
        res = self.someData
        queue1.put(res)
        #print "#78 process 2: put back in queue2 =>", self.someData
        #res = self.someData
        #queue2.put(res)
        #queue2.close()
        #queue2.join_thread()

# main 
if __name__ == '__main__':

    queue1 = Queue()
    #queue2 = Queue()

    global p1, p2
    p1 = Process(target=Load().post(), args=(queue1,))      # process p1
    #p1 = Process(target=Load().post(), args=(queue1,queue2,))
    p1.daemon = True
    p1.start() 

    p2 = Process(target=Unload().get(), args=(queue1,))     # process p2
    #p2 = Process(target=Unload().get(), args=(queue1,queue2,))
    p2.start()
    p2.join()

FRAGE Ich habe andere Ressourcen in Bezug auf überprüft, aber alle beinhalten Kommunikation in eine Richtung. Unten finden Sie eine Liste der Ressourcen.

  1. use-get-nowait-in-python-ohne-leere-ausnahme auszulösen
  2. In-Python-wie-erhalten-Sie-Daten-zurück-von-einem-bestimmten-Prozess-mit-Multiprozess
  3. How-to-Use-Multiprocessing-Warteschlange-mit-Sperre
  4. Das Multiprozessor-Modul unterstützt Sperren
  5. Thread-das-ich-kann-pausieren-und-wieder aufnehmen
  6. Datenaustausch zwischen zwei Python-Prozessen

Wie kann ich den Prozess1 warten lassen und die geänderten Daten von Prozess2 abrufen? Sollte ich einen anderen Ansatz für die Kommunikation zwischen Prozessen in Betracht ziehen, z. B. Pipes, zeroMQ?

VERSUCH 1: Verwenden von time.sleep () ohne die while-Schleife in Prozess 1 Mit nur time.sleep werden die Daten in der Warteschlange nach oben verschoben, erreichen jedoch nie das endgültige Ziel in Prozess 1. Bisher so gut, aber der letzte Schritt fehlt. Die Ergebnisse sind unten.

#20 process 1: put in queue1 => {'process': 'p1', 'timestamp': '2020-02-23 11:40:30.234466', 'class': 'Load()', 'method': 'post()'}
#54 process 2: get from queue1 => {'process': 'p2', 'timestamp': '2020-02-23 11:40:33.239113', 'class': 'Unload()', 'method': 'get()'}
#68 process 2: do something => {'process': 'p2', 'timestamp': '2020-02-23 11:40:36.242500', 'class': 'Unload()', 'method': 'doSomething()'}
#75 process 2: put back in queue1 => {'process': 'p2', 'timestamp': '2020-02-23 11:40:39.245856', 'class': 'Unload()', 'method': 'put()'}

VERSUCH 2: Verwenden der while-Schleife in Prozess 1 Wenn die while-Schleife die Warteschlange überprüft, werden die Daten in die Warteschlange gestellt, aber direkt danach abgefangen. Sie erreichen nie den Prozess 2. Die Ergebnisse sind unten aufgeführt.

#20 process 1: put in queue1 => {'process': 'p1', 'timestamp': '2020-02-23 11:46:14.606356', 'class': 'Load()', 'method': 'post()'}
#28 get from queue1 => {'process': 'p1', 'timestamp': '2020-02-23 11:46:17.610202', 'class': 'Load()', 'method': 'post()'}
#57 queue1 empty

VERSUCH 3: Verwenden von zwei Warteschlangen Verwenden von zwei Warteschlangen: Warteschlange1 von Prozess1 bis Prozess2, Warteschlange2 von Prozess2 bis Prozess1. Die Daten gehen in die Warteschlange1, kehren aber nicht in die Warteschlange2 zurück, sondern verschwinden auf mysteriöse Weise. Die Ergebnisse sind unten.

#20 process 1: put in queue1 => {'process': 'p1', 'timestamp': '2020-02-23 11:53:39.745177', 'class': 'Load()', 'method': 'post()'}
#42 queue2 empty

----- UPDATE 20200224: Versuche 4, 5 und 6 --------------------------------- --------------------------------

VERSUCH 4: Verwenden von zwei Warteschlangen mit manager.Queue ()

Verwenden von zwei Warteschlangen mit dem Manager.Queue (): Warteschlange1 von Prozess1 bis Prozess2, Warteschlange2 von Prozess2 bis Prozess1. Die Daten gehen in die Warteschlange1, kehren aber nicht in die Warteschlange2 zurück, sondern verschwinden auf mysteriöse Weise. Der Code und die Ergebnisse sind unten.

Der Code des Versuchs 4: #! / usr / bin / python2.7 python2.7 # - - Codierung: utf-8 - - # Skript für den serialisierten Datenaustausch zwischen Prozessen

# common modules
import os
import sys
import time
import multiprocessing
from multiprocessing import Process
from multiprocessing import Queue
from multiprocessing import Manager
from datetime import datetime

someData = {}
manager = multiprocessing.Manager()
queue1 = manager.Queue()
queue2 = manager.Queue()

class Load():
    def post(self):
        timestamp = str(datetime.now())
        someData = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
        queue1.put(someData)        # put into queue
        print "#20 process 1: put in queue1 =>", someData
        time.sleep(3)

        # while True:       # queue1 checking loop
        #   if queue1.empty() == False:
        #       timestamp = str(datetime.now())
        #       res = queue1.get()
        #       res = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
        #       print "#28 get from queue1 =>", res
        #       break
        #   else:
        #       print "#31 queue1 empty"
        #       time.sleep(1)

        while True:     # queue2 checking loop
            if queue2.empty() == False:
                timestamp = str(datetime.now())
                res = queue2.get()
                res = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
                print "#39 get from queue2 =>", res
                break
            else:
                print "#42 queue2 empty"
                time.sleep(1)

class Unload():
    def get(self):
        try:
            if queue1.empty() == False:
                data = queue1.get()     # retrieve package from queue
                #queue1.close()
                #queue1.join_thread()
                timestamp = str(datetime.now())
                data = {"process":"p2","class":"Unload()","method":"get()","timestamp":timestamp} 
                print "#54 process 2: get from queue1 =>", data
                self.doSomething(data)  # call method
            else:
                print "#57 queue1 empty"
                pass
        except:
            print "#60 queue1 error"
            pass

    def doSomething(self, data):
        time.sleep(3)
        timestamp = str(datetime.now())
        someData = {"process":"p2","class":"Unload()","method":"doSomething()","timestamp":timestamp}
        self.someData = someData
        print "#68 process 2: do something =>", someData
        self.put()

    def put(self):
        time.sleep(3)
        timestamp = str(datetime.now())
        self.someData = {"process":"p2","class":"Unload()","method":"put()","timestamp":timestamp}
        res = self.someData
        #print "#75 process 2: put back in queue1 =>", self.someData
        #queue1.put(res)
        print "#78 process 2: put back in queue2 =>", self.someData
        queue2.put(res)
        #queue2.close()
        #queue2.join_thread()

# main 
if __name__ == '__main__':

    manager = multiprocessing.Manager()
    queue1 = manager.Queue()
    queue2 = manager.Queue()

    global p1, p2
    #p1 = Process(target=Load().post(), args=(queue1,))     # process p1
    p1 = Process(target=Load().post(), args=(queue1,queue2,))
    p1.daemon = True
    p1.start() 

    #p2 = Process(target=Unload().get(), args=(queue1,))        # process p2
    p2 = Process(target=Unload().get(), args=(queue1,queue2,))
    p2.start()
    p2.join()

Die Ergebnisse des Versuchs 4:

#20 process 1: put in queue1 => {'process': 'p1', 'timestamp': '2020-02-24 13:06:17.687762', 'class': 'Load()', 'method': 'post()'}
#42 queue2 empty

VERSUCH 5: Verwenden einer Warteschlange mit manager.Queue () Verwenden einer Warteschlange mit dem Manager.Queue (): Warteschlange1 von Prozess1 nach Prozess2, Warteschlange1 zurück von Prozess2 nach Prozess1. Die Daten befinden sich in der Warteschlange1, werden jedoch direkt danach abgefangen und erreichen nie den Prozess 2. Die Codeergebnisse sind unten aufgeführt.

Der Code des Versuchs 5:

#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
# script for serialized interprocess data exchange

# common modules
import os
import sys
import time
import multiprocessing
from multiprocessing import Process
from multiprocessing import Queue
from multiprocessing import Manager
from datetime import datetime

someData = {}
manager = multiprocessing.Manager()
queue1 = manager.Queue()
#queue2 = manager.Queue()

class Load():
    def post(self):
        timestamp = str(datetime.now())
        someData = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
        queue1.put(someData)        # put into queue
        print "#25 process 1: put in queue1 =>", someData
        time.sleep(3)

        while True:     # queue1 checking loop
            if queue1.empty() == False:
                timestamp = str(datetime.now())
                res = queue1.get()
                res = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
                print "#33 get from queue1 =>", res
                break
            else:
                print "#36 queue1 empty"
                time.sleep(1)

        # while True:       # queue2 checking loop
        #   if queue2.empty() == False:
        #       timestamp = str(datetime.now())
        #       res = queue2.get()
        #       res = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
        #       print "#44 get from queue2 =>", res
        #       break
        #   else:
        #       print "#47 queue2 empty"
        #       time.sleep(1)

class Unload():
    def get(self):
        try:
            if queue1.empty() == False:
                data = queue1.get()     # retrieve package from queue
                #queue1.close()
                #queue1.join_thread()
                timestamp = str(datetime.now())
                data = {"process":"p2","class":"Unload()","method":"get()","timestamp":timestamp} 
                print "#59 process 2: get from queue1 =>", data
                self.doSomething(data)  # call method
            else:
                print "#62 queue1 empty"
                pass
        except:
            print "#65 queue1 error"
            pass

    def doSomething(self, data):
        time.sleep(3)
        timestamp = str(datetime.now())
        someData = {"process":"p2","class":"Unload()","method":"doSomething()","timestamp":timestamp}
        self.someData = someData
        print "#73 process 2: do something =>", someData
        self.put()

    def put(self):
        time.sleep(3)
        timestamp = str(datetime.now())
        self.someData = {"process":"p2","class":"Unload()","method":"put()","timestamp":timestamp}
        res = self.someData
        print "#81 process 2: put back in queue1 =>", self.someData
        queue1.put(res)
        #print "#83 process 2: put back in queue2 =>", self.someData
        #queue2.put(res)
        #queue2.close()
        #queue2.join_thread()

# main 
if __name__ == '__main__':

    manager = multiprocessing.Manager()
    queue1 = manager.Queue()
    #queue2 = manager.Queue()

    global p1, p2
    p1 = Process(target=Load().post(), args=(queue1,))      # process p1
    #p1 = Process(target=Load().post(), args=(queue1,queue2,))
    p1.daemon = True
    p1.start() 

    p2 = Process(target=Unload().get(), args=(queue1,))     # process p2
    #p2 = Process(target=Unload().get(), args=(queue1,queue2,))
    p2.start()
    p2.join()

Das Ergebnis des Versuchs 5:

#25 process 1: put in queue1 => {'process': 'p1', 'timestamp': '2020-02-24 14:08:13.975886', 'class': 'Load()', 'method': 'post()'}
#33 get from queue1 => {'process': 'p1', 'timestamp': '2020-02-24 14:08:16.980382', 'class': 'Load()', 'method': 'post()'}
#62 queue1 empty

VERSUCH 6: Verwenden der Warteschlangen-Timeouts

Wie vorgeschlagen habe ich versucht, die Zeitüberschreitungen in der Warteschlange zu korrigieren. Der Ansatz ist wieder Warteschlange1 von Prozess1 zu Prozess2, Warteschlange2 von Prozess2 zu Prozess1. Die Daten gehen in die Warteschlange1, kehren aber nicht in die Warteschlange2 zurück, sondern verschwinden auf mysteriöse Weise. Der Code und die Ergebnisse sind unten.

Der Code des Versuchs 6:

#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
# script for serialized interprocess data exchange

# common modules
import os
import sys
import time
import uuid
import Queue
#from Queue import Empty
import multiprocessing
from multiprocessing import Process
#from multiprocessing import Queue
from datetime import datetime

someData = {}

class Load():
    def post(self):
        timestamp = str(datetime.now())
        someData = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
        queue1.put(someData)        # put into queue
        print "#24 process 1: put in queue1 =>", someData
        time.sleep(3)

        # while True:       # queue1 checking loop
        #   if queue1.empty() == False:
        #       timestamp = str(datetime.now())
        #       res = queue1.get()
        #       res = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
        #       print "#33 get from queue1 =>", res
        #       break
        #   else:
        #       print "#36 queue1 empty"
        #       time.sleep(1)

        while True:     # queue2 checking loop
            try:
                someData = queue2.get(True,1)
                timestamp = str(datetime.now())
                someData = {"process":"p1","class":"Load()","method":"post()","timestamp":timestamp}
                print "#43 process 1: got from queue2 =>", someData
                break
            except Queue.Empty:
                print "#46 process1: queue2 empty"
                continue

class Unload():
    def get(self):
        while True:     # queue2 checking loop
            try:
                someData = queue1.get(True,1)
                timestamp = str(datetime.now())
                someData = {"process":"p2","class":"Unload()","method":"get()","timestamp":timestamp} 
                print "#56 process2: got from queue1 =>", someData
                break
            except Queue.Empty:
                print "#59 process2: queue1 empty"
                continue
        self.doSomething(someData)  # call method

    def doSomething(self, data):
        time.sleep(3)
        timestamp = str(datetime.now())
        someData = {"process":"p2","class":"Unload()","method":"doSomething()","timestamp":timestamp}
        self.someData = someData
        print "#68 process2: do something =>", someData
        self.put(someData)

    def put(self,data):
        time.sleep(3)
        timestamp = str(datetime.now())
        self.someData = {"process":"p2","class":"Unload()","method":"put()","timestamp":timestamp}
        someData = self.someData
        #print "#81 process 2: put back in queue1 =>", self.someData
        #queue1.put(res)
        print "#78 process2: put back in queue2 =>", someData
        queue2.put(someData)


# main 
if __name__ == '__main__':

    queue1 = multiprocessing.Queue()
    queue2 = multiprocessing.Queue()

    global p1, p2
    #p1 = Process(target=Load().post(), args=(queue1,))     # process p1
    p1 = Process(target=Load().post(), args=(queue1,queue2,))
    p1.daemon = True
    p1.start() 

    #p2 = Process(target=Unload().get(), args=(queue1,))        # process p2
    p2 = Process(target=Unload().get(), args=(queue1,queue2,))
    p2.start()
    p2.join()

Die Ergebnisse des Versuchs 6:

#24 process 1: put in queue1 => {'process': 'p1', 'timestamp': '2020-02-24 18:14:46.435661', 'class': 'Load()', 'method': 'post()'}
#46 process1: queue2 empty

HINWEIS: Der vorgeschlagene Ansatz funktioniert, wenn ich ihn ohne die Klassen verwende. Der Code ist unten:

import uuid
import multiprocessing
from multiprocessing import Process
import Queue


def load(que_in, que_out):
    request = {"id": uuid.uuid4(), "workload": "do_stuff", }
    que_in.put(request)
    print("load: sent request {}: {}".format(request["id"], request["workload"]))
    while True:
        try:
            result = que_out.get(True, 1)
        except Queue.Empty:
            continue
        print("load: got result {}: {}".format(result["id"], result["result"]))


def unload(que_in, que_out):
    def processed(request):
        return {"id": request["id"], "result": request["workload"] + " processed", }
    while True:
        try:
            request = que_in.get(True, 1)
        except Queue.Empty:
            continue
        print("unload: got request {}: {}".format(request["id"], request["workload"]))
        result = processed(request)
        que_out.put(result)
        print("unload: sent result {}: {}".format(result["id"], result["result"]))


    # main
if __name__ == '__main__':

    que_in = multiprocessing.Queue()
    que_out = multiprocessing.Queue()

    p1 = Process(target=load, args=(que_in, que_out))      # process p1
    p1.daemon = True
    p1.start()

    p2 = Process(target=unload, args=(que_in, que_out))     # process p2
    p2.start()
    p2.join()

----- UPDATE 20200225: Versuch 7 ------------------------------------- -----------------------------------------

VERSUCH 7: Verwenden einer Warteschlange mit Warteschlangenzeitlimits in verschiedenen Klassen (funktioniert)

Bei diesem Versuch verwende ich eine gemeinsame Warteschlange zwischen Methoden verschiedener Klassen mit den korrigierten Zeitüberschreitungen. Die Daten gehen von Prozess1 zu Prozess2 und zurück von Prozess2 zu Prozess1 in einer Shared_queue. Bei diesem Versuch wurden die Daten korrekt übertragen. Der Code und die Ergebnisse sind unten.

Der Code des Versuchs 7:

import uuid
import multiprocessing
from multiprocessing import Process
import Queue

class Input():
    def load(self, shared_queue):
        request = {"id": uuid.uuid4(), "workload": "do_stuff", }
        shared_queue.put(request)
        print("load: sent request {}: {}".format(request["id"], request["workload"]))
        while True:
            try:
                result = shared_queue.get(True, 1)
            except Queue.Empty:
                continue
            print("load: got result {}: {}".format(result["id"], result["result"]))
            break

class Output():
    def unload(self, shared_queue):
        def processed(request):
            return {"id": request["id"], "result": request["workload"] + " processed", }
        while True:
            try:
                request = shared_queue.get(True, 1)
            except Queue.Empty:
                continue
            print("unload: got request {}: {}".format(request["id"], request["workload"]))
            result = processed(request)
            shared_queue.put(result)
            print("unload: sent result {}: {}".format(result["id"], result["result"]))


    # main
if __name__ == '__main__':

    shared_queue = multiprocessing.Queue()
    up = Input()
    down = Output()

    p1 = Process(target=up.load, args=(shared_queue,))      # process p1
    p1.daemon = True
    p1.start()


    p2 = Process(target=down.unload, args=(shared_queue,))     # process p2
    p2.start()

    p1.join()
    p2.join()

Die Ergebnisse des Versuchs 7:

load: sent request a461357a-b39a-43c4-89a8-a77486a5bf45: do_stuff
unload: got request a461357a-b39a-43c4-89a8-a77486a5bf45: do_stuff
unload: sent result a461357a-b39a-43c4-89a8-a77486a5bf45: do_stuff processed
load: got result a461357a-b39a-43c4-89a8-a77486a5bf45: do_stuff processed
2
parovelb 23 Feb. 2020 im 14:23

3 Antworten

Beste Antwort

LÖSUNG: Verwenden einer gemeinsam genutzten Warteschlange

Ich habe das Problem gelöst, nachdem ich den Vorschlägen gefolgt und einige Anpassungen vorgenommen hatte, um das richtige Targeting der verschiedenen Klassenmethoden zu erreichen. Der Hin- und Herfluss der Daten zwischen zwei getrennten Prozessen ist jetzt korrekt. Ein wichtiger Hinweis für mich ist, dem someData -Paket, das zwischen zwei getrennten Prozessen ausgetauscht wird, besondere Aufmerksamkeit zu schenken. Es muss wirklich dasselbe Paket sein, das herumgeworfen wird. Daher der Bezeichnereintrag "id": uuid.uuid4(), um zu überprüfen, ob das Paket bei jeder Passage gleich ist.

#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
# script for back and forth communication between two separate processes using a shared queue

# common modules
import os
import sys
import time
import uuid
import Queue
import multiprocessing
from multiprocessing import Process
from datetime import datetime


someData = {}


class Load():
    def post(self, sharedQueue):
        timestamp = str(datetime.now()) # for timing checking
        someData = {"timestamp":timestamp, "id": uuid.uuid4(), "workload": "do_stuff",}
        self.someData = someData
        sharedQueue.put(someData)       # put into the shared queue
        print("#25 p1 load: sent someData {}: {}".format(someData["id"], someData["timestamp"], someData["workload"]))
        time.sleep(1)   # for the time flow     

        while True:     # sharedQueue checking loop
            try:
                time.sleep(1)   # for the time flow
                timestamp = str(datetime.now())
                someData = sharedQueue.get(True,1)
                someData["timestamp"] = timestamp
                print("#37 p1 load: got back someData {}: {}".format(someData["id"], someData["timestamp"], someData["workload"]))
                break
            except Queue.Empty:
                print("#37 p1: sharedQueue empty")
                continue
            break


class Unload():
    def get(self, sharedQueue):
        while True:     # sharedQueue checking loop
            try:
                someData = sharedQueue.get(True,1)
                self.someData = someData
                timestamp = str(datetime.now())
                someData["timestamp"] = timestamp
                print("#50 p2 unload: got someData {}: {}".format(someData["id"], someData["timestamp"], someData["workload"]))
                break
            except Queue.Empty:
                print("#53 p2: sharedQueue empty")
                continue
        time.sleep(1)               # for the time flow
        self.doSomething(someData)  # pass the data to the method


    def doSomething(self, someData):    # execute some code here
        timestamp = str(datetime.now())
        someData["timestamp"] = timestamp
        print("#62 p2 unload: doSomething {}: {}".format(someData["id"], someData["timestamp"], someData["workload"]))
        self.put(someData)
        time.sleep(1)   # for the time flow


    def put(self,someData):
        timestamp = str(datetime.now())
        someData["timestamp"] = timestamp
        sharedQueue.put(someData)
        print("#71 p2 unload: put someData {}: {}".format(someData["id"], someData["timestamp"], someData["workload"]))
        time.sleep(1)   # for the time flow


# main 
if __name__ == '__main__':

    sharedQueue = multiprocessing.Queue()

    trx = Load()
    rcx = Unload()

    p1 = Process(target=trx.post, args=(sharedQueue,))      # process p1
    p1.daemon = True
    p1.start() 

    p2 = Process(target=rcx.get, args=(sharedQueue,))       # process p2
    p2.start()

    p1.join()
    p2.join()
0
parovelb 26 Feb. 2020 im 09:48

Sie müssen von einem Manager umschlossene Warteschlangen verwenden, um Änderungen prozessübergreifend weiterzugeben. Andernfalls verfügt jeder Prozess über ein separates Warteschlangenobjekt und kann die anderen nicht sehen. Der Manager erstellt eine gemeinsam genutzte Instanz der Warteschlange für alle untergeordneten Prozesse.

So wird queue1 = Queue() zu queue1 = manager.Queue() mit from multiprocessing import Manager an der Spitze. Wenn Sie Ihren Ansatz mit zwei Warteschlangen verwenden möchten, müssen Sie die zweite Warteschlange natürlich auf die gleiche Weise umschließen.

Relevante Ressourcen:

Mehrere Warteschlangen von einem Multiprocessing Manager

Python-Dokumentation

0
adq 23 Feb. 2020 im 12:14

Ich denke, Sie haben gerade die Verwendung von Warteschlangen-Timeouts verpasst

try:
    result = que_out.get(True, 1)
except queue.Empty:
    continue

Dieses vereinfachte Beispiel kann Ihnen helfen:

import uuid
from multiprocessing import Process
from multiprocessing import Queue
import queue


def load(que_in, que_out):
    request = {"id": uuid.uuid4(), "workload": "do_stuff", }
    que_in.put(request)
    print("load: sent request {}: {}".format(request["id"], request["workload"]))
    while True:
        try:
            result = que_out.get(True, 1)
        except queue.Empty:
            continue
        print("load: got result {}: {}".format(result["id"], result["result"]))


def unload(que_in, que_out):

    def processed(request):
        return {"id": request["id"], "result": request["workload"] + " processed", }

    while True:
        try:
            request = que_in.get(True, 1)
        except queue.Empty:
            continue
        print("unload: got request {}: {}".format(request["id"], request["workload"]))
        result = processed(request)
        que_out.put(result)
        print("unload: sent result {}: {}".format(result["id"], result["result"]))

    # main
if __name__ == '__main__':

    que_in = Queue()
    que_out = Queue()

    p1 = Process(target=load, args=(que_in, que_out))      # process p1
    p1.daemon = True
    p1.start()

    p2 = Process(target=unload, args=(que_in, que_out))     # process p2
    p2.start()
    p2.join()

Ausgabe

load: sent request d9894e41-3e8a-4474-9563-1a99797bc722: do_stuff
unload: got request d9894e41-3e8a-4474-9563-1a99797bc722: do_stuff
unload: sent result d9894e41-3e8a-4474-9563-1a99797bc722: do_stuff processed
load: got result d9894e41-3e8a-4474-9563-1a99797bc722: do_stuff processed
1
Man-In wholeEarthMan 23 Feb. 2020 im 12:34