Multithreading in der Praxis

Teil 2: Programmieren für den Multi-Core-Prozessor

Taskverteilung durch mehr Kerne

Dennoch vermag ein geschicktes Design eines Programms auch einen Nutzen für den Einsatz in Multi-Core-Systemen nach sich ziehen. Dies gilt immer dann, wenn die separierten Module auf unterschiedlichen Ausführinstanzen, also unterschiedlichen Cores, abgearbeitet werden. Eine Ausführinstanz in diesem Kontext kann ein CPU-Core, aber auch ein separater Rechner sein. Dieser separate Rechner wiederum kann sich im nahen Umfeld befinden, wie etwa in einem Rechenzentrum, oder auch auf einem anderen Kontinent stehen, wie bei den Service-Orientierten-Architekturen (SOA). Der Unterschied in dieser Betrachtungsweise liegt ja nur in der Distanz der beiden Ausführinstanzen. Bei Multi-Core-CPUs sind die Ausführinstanzen, also die Cores, nur Bruchstücke von Millimetern auseinander, bei SOA-Applikationen tausende von Kilometern.

Vielfach: In je mehr Threads eine Applikation/Routine aufgeteilt ist, desto mehr Cores können parallel arbeiten.
Vielfach: In je mehr Threads eine Applikation/Routine aufgeteilt ist, desto mehr Cores können parallel arbeiten.

Die Herausforderungen an die Softwarenentwicklung sind bei beiden Extremen im Prinzip gleich. Sie hängen davon ab, wie die separierten Software-Fragmente zusammenarbeiten und wie sie synchronisiert werden. In der Regel ist die Möglichkeit der Parallelverarbeitung während der Laufzeit nicht vorhersehbar (nicht deterministisch). Das erfordert ausgefeilte Tools auf der Software-Entwicklungsseite.

Die oben erwähnten Begriffe wie Funktion oder Methode werden in der Softwareentwicklung für Quellprogramme verwendet. Die ausführbaren Module sind in .Net die so genannten .Net-Assemblies. Eine Assembly ist ähnlich wie eine ZIP-Datei, sie stellt eine Paketierung für ein Programm dar. Wird das Programm, die Assembly, tatsächlich ausgeführt, so erfolgt dies in der Regel immer unter der Kontrolle eines Betriebssystems, das dafür einen Prozess, einen Task oder einen Thread generiert.

Der Begriff des Prozesses, des Tasks oder des Threads steht für gerade ausgeführte Programmabschnitte, die unter der Kontrolle eines Betriebssystems ausgeführt werden. Ein Task wiederum ist das aktive Abbild einer Routine oder Methode, meist werden Tasks in Prozessen gruppiert. Der Prozess zerfällt somit in mehrere Tasks. Die Namensgebung ist allerdings nicht ganz eindeutig und wird unterschiedlich angewandt. Der Taskmanager in Windows zeigt eigentlich Programme an. Linux wiederum kennt Prozesse und das passende Kommando ps (Process-Status).

Durch die Modularisierung der Software in das Betriebssystem und die Applikationen mit ihren Assemblies ergibt sich letztendlich eine Vielzahl an Tasks oder Prozessen, je nachdem, welche Namenskonvention vorherrscht.