inter Prozess Kommunikation...

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
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

In DragonPy started quasi die GUI per subprocess die CPU, hier: https://github.com/jedie/DragonPy/blob/ ... py#L49-L74

Beide unterhalten sich dann über sockets: https://github.com/jedie/DragonPy/blob/ ... y#L86-L125

Dabei wird Frage/Antwort per struct.pack() und struct.unpack() gemacht.
Dazu wird ein recht einfaches Format verwendet:

Code: Alles auswählen

    STRUCT_TO_PERIPHERY_FORMAT = (# For sending data to periphery
        "<" # little-endian byte order
        "I" # CPU cycles - unsigned int (integer with size: 4)
        "I" # op code address - unsigned int (integer with size: 4)
        "B" # action: 0 = read, 1 = write - unsigned char (integer with size: 1)
        "B" # structure: 0 = byte, 1 = word - unsigned char (integer with size: 1)
        "H" # Address - unsigned short (integer with size: 2)
        "H" # Bytes/Word to write - unsigned short (integer with size: 2)
    )
https://github.com/jedie/DragonPy/blob/ ... py#L54-L72

Das ganze kommt vom Ursprünglichen ApplePy Projekt.
Flexibel ist das ja nicht gerade, aber ich frage mich ob es eine gute und effektiver Weg ist?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Kommt für dich der Weg über Sockets im multiprocessing-Modul in Frage?
Das Leben ist wie ein Tennisball.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Danke!

Das wäre eine Idee wert, denn das Beispiel sieht auch recht einfach aus (gekürzt):

server:

Code: Alles auswählen

from multiprocessing.connection import Listener

address = ('localhost', 6000)     # family is deduced to be 'AF_INET'
listener = Listener(address, authkey='secret password')

conn = listener.accept()
print 'connection accepted from', listener.last_accepted

conn.send([2.25, None, 'junk', float])

conn.close()
listener.close()
client:

Code: Alles auswählen

from multiprocessing.connection import Client

address = ('localhost', 6000)
conn = Client(address, authkey='secret password')

print conn.recv()                 # => [2.25, None, 'junk', float]

conn.close()
Gerade interessant dabei ist send: http://docs.python.org/2/library/multip ... ction.send
Wobei pickle verwendet wird.

Denke mal alles im allem wird es langsamer, aber wesentlich flexibler...

Ich sollte mir mal generell das multiprocessing Modul ansehen. Denn z.Z. wird der CPU Prozesse mir subprocess "per Hand" gestartet.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@jens:
Per se finde ich die Idee gut, die CPU in einem separaten Prozess laufen zu lassen. Deine ersten Benchmarkzahlen im anderen Thread deuten an, das die CPU-Emulation zum Flaschenhals werden könnte (zumindest für CPython, da ist zwar noch einiges an Optimierungsspielraum, wie ich Dir schon gesagt hatte, aber eine Verdreifachung ist wohl eher unwahrscheinlich). Durch die Prozesstrennung kannst Du die Komponenten z.B. durch nice-Level besser aufeinander abstimmen. Allerdings kann die CPU nur sinnvoll "ticken", wenn die Peripherie auch schnell genug die Daten bereitstellt bzw. abholt. Spätestens bei Spielen mit Soundausgabe (Hatte der Dragon eigentlich Sound?) und internen Timern wirds dann so richtig kniffelig, da die CPU massiven Taktschwankungen unterliegt, die Du teuer korrigieren musst, damit z.B. die Soundausgabe noch anhörbar ist.
(Stichwort realtime, unter heutigem Windows/Linux weisst Du nicht, wann Dein CPU-Prozess wieder ein paar Takte rechnen darf)

Grundsätzlich würde ich an Deiner Stelle versuchen, jede der Komponenten mit so wenig wie möglich Bloatware umzusetzen. Mit Highlevel-Schnittstellen (oder Modulen) kommst Du zwar in der Entwicklung schnell voran, diese können aber in der Summe dazu führen, dass der Emulator unbenutzbar ist und Du große Teile umschreiben musst. In puncto Kommunikation würde ich es pragmatisch angehen - hast Du eine funktionierende Variante, entwickle damit weiter. Zeichnet sich ab, dass die Kommunikation zum Flaschenhals wird, musst Du hier abrüsten. Eine zusätzliche Abstraktion über z.B. ein Drittmodul würde ich ohne Not aus obigen Gründen nicht einführen.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Danke für deine Hinweise... Allerdings ist mein Ziel eh nicht, das es ein vollständiger und Timing genauer Emulator wird. Wozu auch? Den gibt es bereits in Form von XRoar ( http://www.6809.org.uk/dragon/xroar.shtml ) und MESS ( http://mess.org/ ) und jetzt neu, auch in JavaScript mit JMESS: http://jsmess.textfiles.com/

Mein erstes Ziel ist erst mal nur die Lauffähigkeit des BASIC Interpreters.

Dann will ich lieber das machen, was XRoar und MESS nicht machen: Einfache Interaktion mit dem Emulator: z.B. einen separaten BASIC Editor-Fenster, bei den man normal coden kann und per klick wird der Code in den Speicher des Emulators geladen und ausgeführt.

Ob ich überhaupt Sound und Grafik-Ausgabe mache, weiß ich noch nicht.

Das ganze ist auch ehr für mich zum lernen Gedacht und dafür hat es sich für mich schon definitiv gelohnt :)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab die aktuelle Implementierung versucht in Worte zu fassen: https://github.com/jedie/DragonPy/#about-implementation

Dazu noch ein Diagramm:

Code: Alles auswählen

+----------+               +----------+              +--------------------+
| CLI      |  start via    | 6809 CPU |  start in    | CPU control server |
|----------|-------------->|----------|+------------>|--------------------|
|          |  subprocess   |          | same process |                    |
|          |               |          |              |    http server     |
|periphery |               |          |              |                    |
|-Screen   |bus communicate|bus Memory|<-------------|   localhost:6809   |
|-SAM/PIA  |<------------->|   area   |              |                    |
|-cassette |   via socket  |          |              |                    |
+----------+               +----------+              +--------------------+
(Das habe ich bei http://www.asciiflow.com gemacht)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten