fifo-pipe lässt auf sich warten...

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
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

hi!
ich arbeite zur zeit mit fifo-pipes und leider ist das nicht mit erfolg gekrönt:
wenn ich in der python-shell eine fifo-pipe öffne, passiert alles sehr schnell, so wie es sein soll. ich konnte auch eine sehr nette kommunikation zwischen zwei shells herstellen können, aber...
wenn ich nun ein programm schreibe, hängt es sich immer an der fifo auf.
das habe ich per print mitbekommen.
kann das etwas damit zu tun haben, dass ich zwar zuerst eine fifo(server2client) zum schreiben öffne, die andere fifo(client2server) aber zum lesen, bevor der client sie zum schreiben geöffnet hat?

//edit:
der client hat keeine probleme
http://www.cs.unm.edu/~dlchao/flake/doom/
BlackJack

Wie immer wäre es schön wenn man mal hängenden Beispielcode sehen könnte. Ich vermute mal die Ausgaben bei Sender werden gepuffert. Also einfach mal `flush()` aufrufen.
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

ok, ich gebe schon den code^^
aber ich kann schon mal sagen: ich flushe!
Es ist nur ein ausschnitt
der server:

Code: Alles auswählen

    for player in player_list:
        ship_ids.append(arena.initiate_ship(player))
        if player+"_player2server.fifo" not in os.listdir(os.curdir):
            os.mkfifo(player+"_player2server.fifo")
        if player+"_server2player.fifo" not in os.listdir(os.curdir):
            os.mkfifo(player+"_server2player.fifo")
        print "Waiting for player ", player
        fiforead[player] = file(player+"_player2server.fifo", "r")
        fifowrite[player] = file(player+"_server2player.fifo", "w")
    
    ship_command = {"MOV":arena.move,"POS":arena.get_location}
    
    print "Game started!"
    while True:
        print "round #", _round
        starttime = time.time()
        _round += 1
        for ship_id, player in zip(range(1,len(player_list)+1), player_list):
            print "reading fifo..."
            text = fiforead[player].read()
            print "fifo ready..."
            if text:
                #text for example: 'MOV 3,2,1', 'MOV 2,1,4 
                for part in text.split("\n"):
                    if part:
                        print part, part.split()
                        try:
                            commandstring, valuestring = part.split()#['MOV', '3,2,1'] 
                            valuelist = valuestring.split(",")#['3','2','1']
                        except TypeError, ValueError: 
                            continue
  
                        for pos, value in enumerate(valuelist):
                            try:
                                value = int(value)
                                valuelist.pop(pos)
                                valuelist.insert(pos, value)
                            except TypeError, ValueError:
                                pass
der client:

Code: Alles auswählen

#!/usr/bin/env python
print "opening the pipes..."
writer = open("murph_player2server.fifo","w")
reader = open("murph_server2player.fifo","r")
print "pipes are opened"
#writer.write("MOV 2,3,1")
writer.write("POS ?\n")
writer.flush()
print reader.read()
writer.close()
reader.close()
aber selbst wenn ich nicht flushen würde, würde er mir doch eher einen leeren string wiedergeben als gar nichts, oder?
das fand ich nämlich so praktisch: wenn nichts drinsteht, wird die fifo übersprungen

//edit:
jetzt habe ich den client abgebrochen, er hat was gemacht:
fifo ready...
POS ? ['POS', '?']
Traceback (most recent call last):
File "./pywars_xd.py", line 320, in ?
main(a,refresh, ['murph'])
File "./pywars_xd.py", line 262, in main
value = int(value)
ValueError: invalid literal for int(): ?
aber das steht doch in einem try/except-block!
http://www.cs.unm.edu/~dlchao/flake/doom/
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

du hast mit dem except ein kleines gewuzel ;)

wenn du

Code: Alles auswählen

except TypeError, ValueError
machst prüft er, ob es ein TypeError ist, wenn ja speichert er (es) die Errormessage in der Variabel ValueError. Du musst es wie folgt formen, damit auch ValueErrors abgefangen werden. Ob du den Errorstring willst oder nicht ist egal.

Also mit Variabel die den Error beinhaltet

Code: Alles auswählen

except (TypeError, ValueError), ex:
ohne

Code: Alles auswählen

except (TypeError, ValueError):
Greeze DM

Ps: Den rest habe ich mir nicht angeschaut nur auf deine Frage geantwortet
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

ok, dann ist ja schonmal eine der fragen beantntwortet.
wenn ich den client abbreche, dann scheint er ja in der pipe was lesen zu können, flush() scheint nicht zu wirken.
naja, ich werde mal versuchen, von der file-class mir was abzuleiten,
dann kann der skript ja auch noch unter windows ausgeführt werden...
wird dann aber leider langsamer, aber was solls.
http://www.cs.unm.edu/~dlchao/flake/doom/
BlackJack

`read()` liest bis zum Dateiende, das heisst bei Pipes solange bis die andere Seite die Pipe geschlossen hat.

Dein Server hängt also in dem `read()` fest.
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

also klappt es, wenn ich die pipe bei jedem schreiben erst schließe,
flushen ist erfolglos?
http://www.cs.unm.edu/~dlchao/flake/doom/
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Du könntest byteweise oder zeilenweise einlesen...
Antworten