Python: preemptives Multitasking (Multithreading) möglich?

  • Python: preemptives Multitasking (Multithreading) möglich?? Schau mal ob du hier fündig wirst!

  • ich weiß jetzt nicht so recht ob das so stimmt -
    bei leJOS/Java oder C#/Mono oder NQC oder NXC oder RobotC gibt es auch preemptives MT, und das sind auch Interpreter (Bytecode-Interpreter, um genau zu sein).
    Sie arbeiten (von außen betrachtet) fast genau wie POSIX/pthread für compilierte Linux-Executables, per timeslice-scheduler. Der Scheduler ist dabei nicht Bestandteil des Betriebssystems (z.B. Linux oder einem Renessas-H8 OS), sondern der VM mit dem Interpreter.

    Aber wie auch immer, ich benötige zwingend preemptives (Zeitscheiben-) MT für meinen RasPi, damit sehr häufig durchlaufende, schnelle Tasks (z.B. für Sensorabfrage oder PID-Steuerung) nicht durch langdauernde zeitintensive Berechnungen (die aber ruhig oftmals zwischendurch kurzzeitig unterbrochen werden dürfen) blockiert und ausgebremst werden.
    Nach einer gewissen Zeitspanne (z.B. alle 100µs) sichert der Scheduler einfach den kompletten stack und alle Register etc. und switcht dann auf den nächsten Task um, egal ob der alte mit seinem Job fertig geworden ist oder nicht - wenn er dann wieder dran ist, werden die alten Daten zurückgeschrieben und an der alten Stelle weitergemacht usw.

    (in Python werden diese Tasks als Threads bezeichnet, ich verwende die beiden Begriffe hier synonym, obwohl manche unter Threads etwas anderes verstehen als es Python tut.)

    Einmal editiert, zuletzt von HaWe (13. April 2015 um 22:47)

  • Hm ... also nach meinem Verständnis können threads, weil sie keine eigenständigen Prozesse sind, nicht per Multitasking verwaltet werden. Ok, ich kann mich irren, keine Frage ...
    Per Definition läuft aber Dein python-Interpreter unter Linux mit preemptive multitasking - weil Linux, bis auf evtl. Realtime-Varianten, eben preemptive ist.
    Wie da die threads jetzt verwaltet werden ... keine Ahnung ... ich kann mir vorstellen, dass die einfach nach und nach abgeklappert werden.
    Mach aus Deinen threads eigene Prozesse ... dann hast Du imho preemptive multitasking ...

    cu,
    -ds-

  • ich weiß nicht, ob wir aneinander vorbeireden:

    Ein Task kann 10µs brauchen , ein anderer 1ms, wieder ein anderer 10sec.

    Timeslice-MT (wie Java auf einem 8-bit-Prozessor) braucht kein MT-OS, das MT macht die Java-VM. Gleiches gilt für NQC auf einem 8-bit H8 oder Java auf einem ARM7.

    Der Scheduler weist jedem Task z.B. 100µs zu und switcht dann zum nächsten.
    Der 10µs-Task kann in der Zeit 10x durchlaufen, der 1ms-Task wird 10x unterbrochen, bevor er 1x fertig ist (alle 100µs), und der 10sec Task wird 10.000x unterbrochen, währenddesen wieder die beiden anderen wechselweise dazwischenfunken.

    Alle Tasks können aber auch gemeinsame Daten austauschen und darauf zugreifen (z.B. über globale Variablen bzw. Semaphore). Sensible Zugriffe bzw. Zugriffsverletzungen werden üblicherweise über Mutexe geschützt.
    So etwas suche ich für Python.

    Einmal editiert, zuletzt von HaWe (13. April 2015 um 23:08)

  • Hm ... jetzt hast Du mich verwirrt ...


    ...
    Alle Tasks können aber auch gemeinsame Daten austauschen und darauf zugreifen (z.B. über globale Variablen bzw. Semaphore). Sensible Zugriffe bzw. Zugriffsverletzungen werden üblicherweise über Mutexe geschützt.
    So etwas suche ich für Python.


    wie Python seine threads verwaltet, weiss ich, wie gesagt, nicht.
    Oder geht's Dir um gemeinsamen Datenaustausch? :s

    Ah ... gerade erst gesehen: Du hast da noch was angefügt ...
    Also obigen Kram bitte ignorieren ...

    Ok, also: warum teilst Du das dann nicht auf?
    Einen Prozess für die Schreibereien und einen mit dem Rest (wobei Sensor-Abfragen nicht zwangsläufig schnell sind ... eher das Gegenteil ist der Fall).
    Den "wichtigeren" Prozess könntest Du versuchen z.B. per nice höher zu priorisieren.
    Kommunizieren kannst Du über IPC ... so was sollte es auch für Python geben ...

    cu,
    -ds-

  • Hallöchen,

    grundsätzlich ist preemptives Multitasking im Raspbian implementiert. Ich selbst verwende es, um equidistante Abtastungen in meiner C-Lib "jitterarm" zu realisieren. Lies mal in den Man-Pages - Einstiegspunkt etwa hier.
    Mittles einer FIFO scheduling Policy und eines hohen nice-Levels kommst Du mit der Priorität Deines Threads in den Bereich, daß er auch mit Kerneltreibern konkurriert. Damit besteht grundsätzlich die Möglichkeit, eine recht hohe Zeitkonstanz zu erreichen. Die Sache hat aber einen Haken.
    1. wirst Du feststellen, daß der Threadkontextwechsel bereits bei 1ms Zeitscheibe signifikant CPU-Rechenzeit eines Single-Core Raspi's verschlingt, selbst wenn der Thread nix weiter tut, als gleich wieder zu schlafen.
    2. ist es nicht einfach, ein Sleep auf Basis von nanosleep oder µsleep zu implementieren, welches exakt zur angegebenen Zeit aufwacht (Thema Jitterarmut). Willst Du das realisieren, dann wirst Du nur etwa 90% Deiner verbleibenden Zeitscheibe schlafen können und mußt die restliche Zeit mit pollen "verheizen".
    3. Irgendwann fallen die schedulings aller Threads mal zeitlich zusammen. Das ist nur eine Frage des kleinsten gemeinsamen zeitlichen Vielfachen. Wie gehst Du dann mit einer gesprengten Zeitscheibe um?

    100µs halte ich auf dem Single-Core für nicht erreichbar - auch nicht in C!

    Unter Python wird das (zeitlich gesehen) nicht besser aussehen - aber da weis ich auch nicht, welche Funktionalitäten Dir da überhaupt zur Verfügung stehen. Ich kenne mich da nicht gut aus...

    Schöne Grüße

    schnasseldag

  • hallo,
    danke für die Antworten!
    100µs timeslice war nur ein Beispiel, es darf auch ein wenig länger sein.
    Raspbian ist ja Debian-Linux, und auf Linux laufen auch POSIX libs mit pthread, wie schnell aber Zeitscheiben bei pthread oder auch bei der C11-Multithreading-Implementationen sind, weiß ich gar nicht genau.
    Für Arduino Due z.B. ist es ja auch durchaus möglich, für wesentlich kurzfristigere Timing-Probleme neben dem Scheduler auch den DueTimer mit einigen wenigen µs Timmer-IRQs zusätzlich zum Scheduler zu starten. Sollte also 1ms als Grenze für eine Zeitscheibe existieren, wären einige Timer-IRQs im 10-500 µs-Bereich sicher noch eine zusätzliche Option.

    Das vorzeitige Verlassen einer Zeitscheibe ist ja mit yield() etc möglich, und auch delay() oder thread.sleep() etc. stellen Wartezeiten eines Einzel-Tasks dann sofort als nutzbare Rechenzeiten für den nächsten scheduler-task zur Verfügung, indem die Zeitscheibe einfach früher gekappt wird.
    Das sind alles handhabbare - fast - Kleinigkeiten, wenn man ein bisschen Praxis mit pthread oder mit Java- oder ähnlich gestrickten NXC/RobotC-Tasks hat (ich mache das jetzt schon 15 Jahre oder so).

    Notwendig ist es aber schon, dass alle Einzeltasks unter der Haube eines einzigen Programms sind, denn die Menge gemeinam genutzer Variablen, die in dem Moment zur Verfügung stehen müssen, wenn ein Task Rechenzeit erhält, ist einfach zu groß (mindestens 200 MB), außerdem erfordert die Programmstruktur einen gemeinsamen Arbitrator-Task als Steuerung für die restlichen Tasks per Semaphore (für die Subsumption-Behaviour-Architektur - das aber nur am Rande).

    Wichig ist aber hierbei: Mir geht es hier nicht um preemptives MT mit POSIX pthread oder analogen Debian-libs für Executables, sondern um eine Implementierung von pMT ganz speziell für Python, eben wegen seiner Einfachheit !

    (Eine Alternative wäre höchstens eine andere C-Programmierumgebung, die pMT unterstützt, die müsste aber von der IDE sehr einfach gestrickt sein, ähnlich wie die Arduino-Sketch-IDE. Eclipse und makefile oder auch VS mit C# und die ganze übrige .NET-Familie - und übrigens auch JAVA - hasse ich wie der Teufel das Weihwasser.
    Wenn da wer was wie Sketch C für RasPi kennt, das wäre auch super.)

    Wen es interessiert, wie einfach es mit pthread geht (das ist in etwa so, wie ich es mir auch für Python etc. vorstelle), hier ein kleines altes Testprogramm (wirklich nur als grundsätzliche Demo für die pMT-Verwaltung, später sehen alle Tasks völlig anders aus:

    Einmal editiert, zuletzt von HaWe (14. April 2015 um 12:25)

  • Hast Du mal gurgel befragt ...
    Da finden sich einige interessante Sachen in dieser Richtung. Unter anderem, wie ich auch schon meinte, eigene Prozesse die über IPC miteinander reden oder event-basiert wie z.B. twisted ...

    Wobei mir letzteres absolut nichts sagt ;)

    cu,
    -ds-

  • ein Task muss auch andere starten und stoppen können, wie mit
    pthread_create...
    pthread_kill...
    pthread_mutex_lock...
    pthread_join...

    ich habe auch schon einen Tipp mit concurrent.futures bekommen, aber das ist 3 Nummern zu groß für mich - wenn es überhaupt geht. Bin ja selber gerade bei den allerersten theoretischen Python-Gehversuchen und checke noch ab, ob der RasPi überhaupt geeignet ist für meine Projekte.

  • Ah ok ...
    Klingt ja fast so, als kämst Du aus der C-Ecke ;)
    Das kann ich dann sehr gut nachvollziehen ... Gottseidank habe ich es bisher geschafft, einen Bogen um Schlangen-Kacke ... äh -Kot ... ähm ... -Code zu machen und habe auch nicht vor, mich auf die Würgerei einzulassen :)

    bye,
    -ds-

  • also C ist schon sehr mächtig, und man kann es durchaus sogar richtig gut lesbar schreiben, wenn man will.
    Aber ich nutze an sich auch nur ANSI C, kein echtes C++, bzw. nur vereinfachtes C++ wie bei Sketch.
    Mit gpp C/C++ und Eclipse und makefile und gdb kannst du mich auch jagen.
    Sketch für RasPi wäre dagegen ideal.
    Aber auch Python käme mir da sehr gelegen, weil man die ganzen Monster-IDEs nicht braucht.
    Aber meine Projekte (Subsumption / Behaviour-Architektur, lernfähige neuronale Netze, Mustererkennung, Navigation, Sensor Fusion, paralleles Motor-PID-Controlling für ein Dutzend Encoder-Motore) brauchen auch gewisse Programmiersprachen-Features, und pMT gehört da wirklich zwingend dazu - und es muss einfach beherrschbar sein.

    Einmal editiert, zuletzt von HaWe (14. April 2015 um 23:07)

  • Bevor wir jetzt komplett abgleiten ...
    Ich kann Dir da leider nicht weiterhelfen ... so gerne ich das auch täte.
    Aber Du klingst so, als wüsstest Du wovon Du redest und ich traue Dir durchaus zu, dass Du da eine passable Lösung finden wirst.
    Viel Erfolg bei Deine(n/m) Projekt(en),
    -ds-

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!