Python Multithreading

Gast #3140382
Lesenswert?

Hey,

ich habe folgendes Problem. Ich habe ein Hauptprogramm in welchem ich 
zur Zeit nach Bluetooth Geräten suche. Der Scann nimmt einige Sekunden 
in Anspruch, weswegen mein Hauptprogramm stehen bleibt.

Kann ich die Performance durch Multithreading verbessern? Also ich 
starte einen Thread, in welchem am laufenden Band nach BT Geräten 
gescannt wird und nutze dessen Resultate im Haupthread.

Ich bin leider Neuling, was das angeht und wäre deshalb über Hilfe sehr 
dankbar. Evtl. kann mir ja jemand ein Grundgerüst geben.

Danke und schönen Abend!
Gast #3140446
Lesenswert?

Also das Programm ist ein Konsolenprogramm und recht simpel. Das Schema 
ist ungefähr wie folgt:



while(1):

TASTER_LESEN
   if(TASTER):
      SUCHE_NACH_BESTIMMTER_BLUETOOTH_MAC
      ...
      MACHE_ETWAS_WENN_BESTIMMTE_MAC_GEFUNDEN




Jetzt möchte ich quasi immer im Hintergrund nach den BT-Geräten in der 
Umgebung suchen um das Ganze zu parallelisieren.
Gast #3140453
Lesenswert?

Anderson schrieb:
> Hey,
>
> ich habe folgendes Problem. Ich habe ein Hauptprogramm in welchem ich
> zur Zeit nach Bluetooth Geräten suche. Der Scann nimmt einige Sekunden
> in Anspruch, weswegen mein Hauptprogramm stehen bleibt.
>
> Kann ich die Performance durch Multithreading verbessern? Also ich
> starte einen Thread, in welchem am laufenden Band nach BT Geräten
> gescannt wird und nutze dessen Resultate im Haupthread.
>
> Ich bin leider Neuling, was das angeht und wäre deshalb über Hilfe sehr
> dankbar. Evtl. kann mir ja jemand ein Grundgerüst geben.
>
> Danke und schönen Abend!

Python erleidet noch den GIL, daher wäre es besser mit einem 
(Hintergrund) Prozess zu arbeiten.
Das geht übrigens ganz hervorragend in Python.
Gast #3140476
Lesenswert?

Anderson schrieb:
> GIL? Kannst du mir das mit Hintergrundprozessen bitte näher erläutern?

GIL ist der Global Interpreter Lock.
Gibt's im Weltnetz eine Menge Informationen dazu.
Wichtig ist nur: Threading geht, kann aber (leichte) Perfomance Probleme 
geben.

Auf Unixoiden Betriebssystemen kann man wunderbar os.fork() nehmen
Zu Windows kann ich nichts schlaues sagen (wer schon?)
1
def child_process():
2
    return
3

4
def parent_process():
5
    return
6

7
def main():
8
    pid = os.fork()
9
    if (pid == 0):
10
        child_process()
11
    parent_process()
12
    os.waitpid(pid, 0)          # wait for child to exit
13
    sys.exit(0)

http://docs.python.org/2/library/os.html#os.fork
#3140485
Lesenswert?

Wie sollen der Thread "BT suchen" und "BT verarbeiten" miteinander 
kommunizieren? Wie stellst Du dir das vor. Diese Funktionalitäten sind 
von einander abhängig.

Ein parallelisiertes Programm stellt andere Anforderungen an den 
Programmaufbau als eine sequenzielles Programm.

Als "Neuling" solltest du erst mal das sequenzielle Programm zum laufen 
bringen und es dann für Multithreading erweitern. Immer einen Schritt 
nach dem Anderen.

Grüsse
Gast #3140494
Lesenswert?

Markus M. schrieb:
> Wie sollen der Thread "BT suchen" und "BT verarbeiten" miteinander
> kommunizieren? Wie stellst Du dir das vor. Diese Funktionalitäten sind
> von einander abhängig.
>
> Ein parallelisiertes Programm stellt andere Anforderungen an den
> Programmaufbau als eine sequenzielles Programm.
>
> Als "Neuling" solltest du erst mal das sequenzielle Programm zum laufen
> bringen und es dann für Multithreading erweitern. Immer einen Schritt
> nach dem Anderen.
>
> Grüsse

Das Sequentielle Programm läuft perfekt. Im Grunde genommen möchte ich 
herausfinden, ob ein bestimmtes BT-Gerät in der Nähe ist.


Die Kommunikation zwischen den Threads möchte ich gerne wie folgt haben. 
Es gibt eine "globale" Variable: device_on. Diese kann True oder False 
sein. Sagen wir zu Programm Start ist sie False.

Der Scann Thread setzt diese Variable nun auf True oder False, je 
nachdem, ob das Gerät an oder aus ist.

Der Verarbeitunsthread reagiert anders je nachdem, ob device_on True 
oder False ist. Wenn kein neuer Wert vom Scann Thread geliefert wird, 
nimmt es den alten Wert.
Gast #3140522
Lesenswert?

Anderson schrieb:
> Ok was ist denn eurer Meinung nach die einfachste Möglichkeit, das von
> mir gewünschte Verhalten zu erreichen? Threads, Prozesse?

Bei Thread brauchst du keine InterProcessCommunication.
Das machts einfacher. Dafür kann GIL zuschlagen.

Mit Prozessen benutzt du auch wirklich mehrere Kerne in der CPU
und bist das GIL Problem los.
Der Mehraufwand für IPC ist einmal eine Stunde einlesen und ein paar 
Quickies tippen.

Das Framework kannst du dann später immer wieder nutzen.

Teste mit Threading und wenns Gut und Performant geht, prima.
Ansonsten Prozesse mit IPC, das ist die elegantere Methode
#3140537
Lesenswert?

Das einfachere dürften Treads sein. Kommunikation über 
Funktionsparameter und Rückgabewert geht dann nicht mehr. Datenaustausch 
nur über Datenstrukturen. Du musst dann sicherstellen, das sich die 
Threads beim Zugriff auf die Datenstruktur nicht in die Quere kommen.

Schau dir das Thread Interface von Python an. Normalerweise muss dann 
nur die Funktion als Thread gestartet werden.

Beispiel:
Funktion "sucheBT" erstellen
Funktion "bearbeitBT" erstellen
Thread erstellen createThread( sucheBT )
Thread erstellen createThread( bearbeiteBT )

Die Steuerung der Funktionen muss jetzt über Datenstrukturen erfolgen 
z.B. http://de.wikipedia.org/wiki/Endlicher_Automat

Grüsse

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren