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!
Beschreibe doch mal den Programmablauf. Dann ist es auch möglich dir Hilfestellung zu geben, wo Du mit dem Multithreading ansetzen kannst. Consolen oder GUI Programm? Grüsse
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.
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.
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
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
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.
Norbert schrieb: > Anderson schrieb: > Auf Unixoiden Betriebssystemen kann man wunderbar os.fork() nehmen > Zu Windows kann ich nichts schlaues sagen (wer schon?) > def child_process(): > return > > def parent_process(): > return Danke für die Antwort. Nur wie tausche ich nun zwischen beiden Prozessen Daten aus?
Anderson schrieb: > Nur wie tausche ich nun zwischen beiden Prozessen Daten aus? Schau dir auch noch einmal das Modul multiprocessing an. Da gibt's dann sowohl Queues als auch Pipes.
Zwischen Prozessen kannst Du nur über die vom BS bereitgestellten Mittel kommunizieren. Shared Memory, Filesystem oder Netzwerk. Grüsse
Ok was ist denn eurer Meinung nach die einfachste Möglichkeit, das von mir gewünschte Verhalten zu erreichen? Threads, Prozesse?
Und wenn es nur um eine true/false Info geht, könnte man es am allereinfachsten via Semaphore machen. Aber ob Python das kennt, kann ich nicht sagen.
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
Jens G. schrieb: > allereinfachsten via Semaphore machen. Aber ob Python das kennt, kann > ich nicht sagen. Siehste, die habe ich noch vergessen. Sind auch in multiprocessing...
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
Also um Performance und mehrere Kerne geht es nicht. Das Programm läuft auf einem Raspberry Pi. Also denke ich mal, das Threads angebracht sind. Bisher habe ich aber leider noch kein minimales Grundgerüst gefunden.
Wenn es auf dem Raspberry Pi laufen soll, hast Du dort die PThread Library zur Verfügung. Ein Wrapper für Python sollte verfügbar sein. Schau dir mal die Beispiele zu PThread an. Hab hier ein Tutorial gefunden. Vielleicht hilft es: http://www.python-kurs.eu/threads.php Grüsse
Warum so kompliziert? Im Modul threading (siehe Python Doku) ist alles drin was du brauchst, Threads und Semaphore. Und das GIL ist für Deine Aufgabe kein Hindernis.
Danke ich habe es jetzt mit: allocate_lock() und start_new_thread() gelöst und es scheint zu funktionieren. Meintet ihr das mit Semaphore?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.