Forum: PC-Programmierung Python - Multitasking


von Felix C. (felix_c13)


Lesenswert?

Hallo Leute,

Ich habe ein Programm in dem ich gleichzeitig per Socket an einem Port 
lauschen will und andererseits Keyboard eingaben einlesen will. Da ja 
input() blockiert war die Idee zwei Threads zu erstellen die Events in 
Queues legen.

Mein Programm sieht etwa so aus(bin grad auch nicht mehr bei der 
Arbeit):

def listen_input(input_queue):
     while TRUE:
            print 'a'
            input_queue.put(sys.stdin(1))
            print 'c'

def listen_client(client_queue):
     while TRUE:
            print 'b'

input_queue = Queue.Queue()
client_queue = Queue.Queue()

input_thread = threading.Thread(target=listen_input, 
args=(input_queue,))
client_thread = threading.Thread(target=listen_client, 
args=(client_queue,))
input_thread.daemon = True
client_thread.daemon = True
input_thread.start()
client_thread.start()

i = 0
while TRUE:
      i = i+1
      time.sleep(1)
      print 'd'

Wenn ich jetzt das Program starte krieg ich halt n paar b's und EIN a. 
Danach kommen halt lauter d's. Ich bin mir ganz sicher, er steckt halt 
bei listen_input fest. Wenn ich enter drücke kommt immer 'ca', wegen dem 
carriage return.

Ich muss ehrlich sagen, dass ich noch wenig von Phyton verstehe (gestern 
angefangen), aber es kann doch nicht so schwer sein, dass er so 
round-robin-mässig durch die Threads switcht. Btw. der "Main-Thread" hat 
anscheinend eine höhere Priorität was?

Was ich auch nicht verstehe, wenn ich iwie 50mal n 'x' bei der Tastatur 
eingebe, krieg ich ne Menge 'ca' aber nie ein b. Das heisst also, dass 
er selbst wenn er nicht blockiert wird, nie in den anderen Thread 
wechselt, wieso?

Gruss und Dank

Felix

Edit: Also wenn ich meinetwegen 50 'x' eingebe und dann Enter drücke.

: Bearbeitet durch User
von retta (Gast)


Lesenswert?

input_queue.put(sys.stdin(1))

??

Probier mal deine Funktion ohne Multithreading..

von Carl D. (jcw2)


Lesenswert?

Wo wird der Listen-Thread gestartet?

von Felix C. (felix_c13)


Lesenswert?

retta schrieb:
> input_queue.put(sys.stdin(1))

sry sys.stdin.read(1) meinte ich

Hab ich schon. aber das geht ja nicht

Carl D. schrieb:
> Wo wird der Listen-Thread gestartet?

Hä welcher?

: Bearbeitet durch User
von Carl D. (jcw2)


Lesenswert?

Sorry, zu oberflächlich draufgeschaut.

von flof3000 (Gast)


Lesenswert?

Threads sind ein der komplexeren Methoden sowas zu machen - weil die 
Interaktion schnell undurchschaubar wird.

Besser ist's sowas mit asynchronem IO zu machen - in 'gross' mit 
Twisted,
aber für diesen simplen Fall würde es auch select.select tun.

ready_to_read, ready_to_write, ready_with_exception = 
select.select([sys.stdin, dein_socket]) kommt genau dann wieder,
wenn entweder sys.stdin oder dein_socket Daten geliefert haben.
Dann musst du nur noch in ready_to_read schauen, welcher es jetzt genau 
war.

von Felix C. (felix_c13)


Lesenswert?

flof3000 schrieb:
> Threads sind ein der komplexeren Methoden sowas zu machen - weil
> die
> Interaktion schnell undurchschaubar wird.
>
> Besser ist's sowas mit asynchronem IO zu machen - in 'gross' mit
> Twisted,
> aber für diesen simplen Fall würde es auch select.select tun.
>
> ready_to_read, ready_to_write, ready_with_exception =
> select.select([sys.stdin, dein_socket]) kommt genau dann wieder,
> wenn entweder sys.stdin oder dein_socket Daten geliefert haben.
> Dann musst du nur noch in ready_to_read schauen, welcher es jetzt genau
> war.

Funktioniert select nicht nur auf Linux? Sry, ich muss das auf Windows 
(unabhängig von eigenen Interessen). Und jetzt ne Cygwin-Nummer abziehen 
geht auch nicht

Vielen Dank trotzdem

Gruss

Felix

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

PythonWin 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit 
(AMD64)] on win32.
Portions Copyright 1994-2008 Mark Hammond - see 'Help/About PythonWin' 
for further copyright information.
>>> import select
>>> dir(select)
['__doc__', '__file__', '__name__', '__package__', 'error', 'select']
>>> help(select)
Help on module select:

NAME
    select - This module supports asynchronous I/O on multiple file 
descriptors.



geht !

von Felix C. (felix_c13)


Lesenswert?

Dennis H. schrieb:
> geht !

hatte nur gelesen, dass es nicht geht und auch in der Wiki steht was in 
die Richtung:
https://docs.python.org/2/library/select.html

Aber, dann freue ich mich.

Danke euch allen!

von Florian F. (flof3000)


Lesenswert?

In der Tat geht select nicht mit Pipes unter Windows - stdin wird so 
nix.
Aber es gibt equivalente Mechanismen mit WaitForMultipleObjects und 
so...

Wenn ich das unter Windows machen muesste, wuerde ich aber massiv zu 
Twisted tendieren. Beispiel hier: 
http://twistedmatrix.com/documents/current/_downloads/stdiodemo.py

von Yalu X. (yalu) (Moderator)


Lesenswert?

Ab Python 3.4 gibt es das Modul selectors, das einen Wrapper für
verschiedene OS-Primitive darstellt und deswegen nicht an das
Unix-select gebunden ist:

  https://docs.python.org/3/library/selectors.html

von Felix C. (felix_c13)


Angehängte Dateien:

Lesenswert?

Also ich hab das Ganze jetzt zum Laufen gebracht, mit Threads. Ich habe 
absolut keine Ahnung wieso diese gestern nicht funktioniert haben. Heute 
haben sies^^

Ich habe das Programm mal noch geaddet, vielleicht hilfts einem ja mal 
noch.
Für Kritik jederzeit offen :D

Noch ne kurze Frage am Rande. Kann es sein, dass man bei der 
PC-Programmierung, zumindest bei kleineren Programmen nicht so penibel 
auf Effizienz achtet, und auch oft bei all den Modulen die man benutzt 
nicht so richtig weisst, was sie machen? Ich komme jetzt von der 
Mikrocontroller-Seite. Da weiss man iwie immer wie schnell der Prozessor 
läuft, weiss, was das etwa bedeutet und kann Instruktion per Instruktion 
durch seinen Code steppen, (wenn man den Source-Code hat). Bei einem PC 
scheinen mir solche Grössen weniger "fassbar", es gibt viel mehr 
Abhängigkeiten, das eigene Programm ist immer nur eines von vielen die 
gerade laufen.

Gruss

Felix

von Sascha W. (sascha-w)


Lesenswert?

Felix C. schrieb:
> Also ich hab das Ganze jetzt zum Laufen gebracht, mit Threads. Ich habe
> absolut keine Ahnung wieso diese gestern nicht funktioniert haben. Heute
> haben sies^^
>
> Ich habe das Programm mal noch geaddet, vielleicht hilfts einem ja mal
> noch.
> Für Kritik jederzeit offen :D
noch paar Anregungen:
1. deine Loop die die Queues leert dürfte in der Art ziemlich viel 
Rechleistung verbraten, mach solange beide Queues leer sind wenigstens 
einen kleinen Sleep.
2. was passiert wenn die TCP-Verbindung geschlossen wird? Da solltest du 
noch für eine geordnetes Ende sorgen, bzw. dafür das zu einem späteren 
Zeitpunkt wieder eine Verbindung angenomen werden kann.

> Noch ne kurze Frage am Rande. Kann es sein, dass man bei der
> PC-Programmierung, zumindest bei kleineren Programmen nicht so penibel
> auf Effizienz achtet, und auch oft bei all den Modulen die man benutzt
> nicht so richtig weisst, was sie machen? Ich komme jetzt von der
> Mikrocontroller-Seite. Da weiss man iwie immer wie schnell der Prozessor
> läuft, weiss, was das etwa bedeutet und kann Instruktion per Instruktion
> durch seinen Code steppen, (wenn man den Source-Code hat). Bei einem PC
> scheinen mir solche Grössen weniger "fassbar", es gibt viel mehr
> Abhängigkeiten, das eigene Programm ist immer nur eines von vielen die
> gerade laufen.
Tja das ist halt so in einem Multitaskingsystem. Trotzdem sollte man mal 
in Taskmanager schauen was das Program so tut. An sonsten reicht die 
Performance für die Aufgabe mit der gewählte Programmiersprache aus oder 
eben nicht.

Sascha

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.