threading und Queue

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
XCDRiVER
User
Beiträge: 31
Registriert: Sonntag 12. Februar 2017, 19:59

Hallo Forum,
ich habe zwei Klassen, die einzeln durch threading.Thread gestartet werden.
Um Informationen zwischen beiden Klassen auszutauschen wollte ich die multiprocessing.Queue() Klasse benutzen,
geht das überhaupt oder funktioniert Queue nur im Zusammenhang mit Process?

Ich konnte bislang keinen Beispielcode dazu finden, hättet ihr da mal einen Link für mich, wo ich mir das mal anschauen kann?
vielen Dank
Benutzeravatar
XCDRiVER
User
Beiträge: 31
Registriert: Sonntag 12. Februar 2017, 19:59

Ach sorry, ich hab nun doch einen Weg gefunden dass es erst mal läuft.
[codebox=pycon file=Unbenannt.txt]
from multiprocessing import Queue
import threading

class Eins(object):

data = 512

def __init__(self, q):
self.q = q
self.q.put(self.data)

class Zwei(object):

def __init__(self, q):
self.q = q
self.dataZwei = self.q.get()
print(self.dataZwei)

if __name__ == "__main__":

q = Queue()

eins = threading.Thread(target=Eins, args=(q,))
eins.start()

zwei = threading.Thread(target=Zwei, args=(q,))
zwei.start()[/code]
BlackJack

@XCDRiVER: Ich würde diese Queue nicht ohne/ausserhalb von `multiprocessing` verwenden. Es gibt `Queue.Queue`.
Benutzeravatar
XCDRiVER
User
Beiträge: 31
Registriert: Sonntag 12. Februar 2017, 19:59

ah, danke für den Tipp, ich schaue mal in die docs.
Benutzeravatar
XCDRiVER
User
Beiträge: 31
Registriert: Sonntag 12. Februar 2017, 19:59

hallo Leute,
ich krieg es nicht hin :|
ich möchte eigentlich Daten hin und her schicken.
Es wird aber nur die erste Nachricht durchgegeben, data="eins". Zumindest denke ich das.
Ich brauche mal einen Tipp was ich falsch mache.

Code: Alles auswählen

from queue import Queue
import threading

class Eins(object):

    data = "eins"

    def __init__(self, q):
        self.q = q
        self.q.put(self.data)
        self.dataEins = self.q.get()
##        self.q.task_done()
        print(self.dataEins)
 
class Zwei(object):

    data = "zwei"
   
    def __init__(self, q):
        self.q = q
        self.dataZwei = self.q.get()
##        self.q.task_done()
        print(self.dataZwei)
        self.q.put(self.data)
        print("geschickt")
        
if __name__ == "__main__":

    q = Queue()

    eins = threading.Thread(target=Eins, args=(q,))
    zwei = threading.Thread(target=Zwei, args=(q,))

    eins.start()
    zwei.start()

die Ausgabe ist:

eins


gewünschte Ausgabe ist:

eins
zwei
geschickt
Benutzeravatar
XCDRiVER
User
Beiträge: 31
Registriert: Sonntag 12. Februar 2017, 19:59

hmm,
ich denke fast das die queue.Queue() anders als die multiprocessing.Queue() nicht in beide Richtungen funktioniert.
habe hier (https://pymotw.com/2/Queue/) gerade was von Dequeue gelesen. ...
ich schau mir das noch mal an...
Benutzeravatar
XCDRiVER
User
Beiträge: 31
Registriert: Sonntag 12. Februar 2017, 19:59

ich glaube das Dequeue() nicht das ist was ich brauche,
wenn ich das richtig verstehe, kann ich damit eine bestehende Pipe von der einen oder anderen Öffnung lesen.
Ich muss aber Daten unabhängig voneinander hin und her transportieren, nach dem FIFO Prinzip.
Sollte ich vielleicht mehrere queue.Queue() benutzen?
So jeweils eine für Hin- und Rücktransport?
Macht man das so für Kommunikation unter Klassen?

vielen Dank
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

XCDRiVER hat geschrieben:ich glaube das Dequeue() nicht das ist was ich brauche
Was Du brauchst ist Queue. Dies ist ein threadsicherer Wrapper um dequeue.

Code: Alles auswählen

import time
from threading import Thread
from queue import Queue, Empty


def send(queue, message_nums=10):
    for n in range(message_nums):
        time.sleep(0.2)
        queue.put('message number: {}'.format(n))
        
        
def receive(queue):
    while True:
        try:
            message = queue.get(timeout=1)
        except Empty:
            break
        print(message)
    print('done.')
    

queue = Queue()
Thread(target=send, args=(queue,)).start()
Thread(target=receive, args=(queue,)).start()
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@kbr: soweit war XCDRiVER doch schon. Nur ist eben eine Queue wie jedes handelsübliche Rohr nur zum Transport in eine Richtung geeignet. Neben einer Wasserzuleitung braucht man eben auch noch ein Abwasserrohr.

@XCDRiVER: wo hast Du Schwierigkeiten zwei Queues zu benutzen?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Sirius3 hat geschrieben:@kbr: soweit war XCDRiVER doch schon.
Ah, zu oberflächlich gelesen. Na dann eben zwei Queues.
Benutzeravatar
XCDRiVER
User
Beiträge: 31
Registriert: Sonntag 12. Februar 2017, 19:59

hallo kbr, hallo Sirius3,
danke für die Rückmeldung,
ich hatte die Queue zuerst mit multiprocessing im Test, dort funktioniert die Queue in beide Richtungen, lesen und schreiben.
Ich wusste nicht, dass die queue.Queue() nur in eine Richtung funktioniert, dass erklärt natürlich das Verhalten im Test.
Ich probiere mal mit mehreren Queue herum, zum schreiben und zum lesen,
wichtig ist mir nur, das ich eine saubere Lösung für den Informationsaustausch zwischen den Klassen finde.
Ich denke mal das wird jetzt schon ganz gut.
Vielen Dank euch
Antworten