Wie man Multithreading in zwei verschiedenen Programmiersprachen beherrscht

Seit Jahrzehnten wird in der Computerwerbung die Leistungsfähigkeit von Multithreading als Antwort auf die Kundenwünsche nach mehr Leistung angepriesen. Die Anzahl der Kerne, die einem Computer zur Verfügung stehen, ist in den letzten Jahren sprunghaft angestiegen, von vier auf acht oder zehn. Aber was ist Multithreading und wie kann ein Computerprogrammierer darauf zugreifen? In diesem Artikel werfen wir einen genauen Blick auf Multithreading und untersuchen, wie es für spürbare Leistungssteigerungen in zwei der beliebtesten heute verfügbaren Programmiersprachen – Java und Python – eingesetzt werden kann.

Was ist Multithreading?

Was ist Multithreading?

Grundsätzlich ist Multithreading eine effiziente Möglichkeit, mehrere Aufgaben gleichzeitig auszuführen, die häufig vom selben Programm zugewiesen werden. Diese Aufgaben werden auf der kleinsten Ebene verwaltet, die dem Programmierer zur Verfügung steht, um sicherzustellen, dass Konflikte zwischen Threads minimal sind und die Systemressourcen optimal genutzt werden. Diese Verwaltungsebene wird als Thread bezeichnet. Ein Thread ist ein aktiver Teil eines Prozesses, also einer Aktion, die ein Programm ausführt. In einem Textverarbeitungsprogramm würde beispielsweise das Speichern Ihrer Datei als Prozess betrachtet, während die Aktion des Zuweisens des Speicherplatzes zum Speichern der Datei als Thread betrachtet würde.

In diesem Artikel geht es um Threads auf Benutzerebene, die von einem Benutzer oder einem vom Benutzer erstellten Programm, beispielsweise einer Anwendung, erstellt werden. Threads auf Kernel-Ebene (und in Java Daemon-Threads) werden hier nicht behandelt. Threads auf Kernel-Ebene sind spezifisch für ein bestimmtes Betriebssystem und die Implementierung durch ein System dauert lange, während Daemon-Threads automatisch von der Java Virtual Machine erstellt werden, um Threads auf Benutzerebene zu bedienen. Weder Daemon-Threads noch Threads auf Kernel-Ebene werden normalerweise vom durchschnittlichen Programmierer erstellt und werden daher hier nicht behandelt.

Bitte beachten Sie außerdem, dass Multithreading nicht derselbe Begriff ist wie Multitasking. Multitasking findet auf Systemebene statt und beinhaltet die Speicherverwaltung durch das Betriebssystem, um sicherzustellen, dass zwei Programme gleichzeitig arbeiten können. Multithreading hingegen findet auf Thread-Ebene statt, die viel kleiner ist, und obwohl es immer noch in gewissem Maße Speicherverwaltung erfordert, geht es hauptsächlich um die Zuweisung von Threads (und damit Prozessen) zu mehreren Kernen. Während Multithreading immer noch auf einem Single-Core-Computer verwendet werden kann, werden die größten Vorteile der Technik durch die Verwendung auf Multicore-Computern erzielt. Wenn jeder Thread im gemeinsam genutzten Speicher auf einem anderen Kern einer Multicore-Maschine ausgeführt wird, wird diese Technik als parallele Ausführung oder einfacher als Parallelität bezeichnet.

Wenn der Programmierer ein Multithread-Programm auf einem Single-Core-Computer ausführt, werden mehrere Threads gleichzeitig an den einzelnen Prozessor gesendet. Der Prozessor erledigt die in den Threads enthaltenen Aufgaben so schnell wie möglich und akzeptiert dabei so viele Threads wie möglich. Entsprechend oracle.comDiese Technik wird als gleichzeitige Ausführung oder einfacher als Parallelität bezeichnet.

Multithreading auf einem Single-Core-Prozessor – lohnt es sich?

Multithreading auf einem Single-Core-Prozessor – lohnt es sich?

Obwohl es sinnlos erscheint, ein Multithread-Programm für einen Single-Core-Prozessor zu erstellen, ist dies möglicherweise nicht der Fall. Moderne Prozessoren sind extrem schnell und häufig werden Engpässe durch die Geschwindigkeit der Ein-/Ausgabebusse und -geräte und nicht durch den Prozessor selbst verursacht. Wenn beispielsweise ein Thread die Auslastung einer relativ langsamen Festplatte erfordert, können andere Threads in einem Multithread-Programm abgeschlossen werden, während der „erste“ Thread noch auf die Festplatte zugreift. Im Vergleich dazu muss bei Verwendung herkömmlicher Programmiertechniken das gesamte Programm warten, bis der Thread, der auf die Festplatte zugreift, abgeschlossen ist.

Die Erstellung von Multithread-Programmen für einen Single-Core-Prozessor kann einen Nachteil haben. Wenn im Multithread-Programm zu viele Threads ausgeführt werden, als dass der Prozessor sie gleichzeitig verarbeiten könnte, könnten die Threads möglicherweise den Prozessor verlangsamen, was natürlich zu Leistungsproblemen führen könnte. Ein weiteres Problem, das Sie beim Codieren eines Multithread-Programms für einen Single-Core-Computer beachten sollten, besteht darin, dass der Threading-Verwaltungsprozess zu viel Speicher beanspruchen und tatsächlich den gesamten Computer verlangsamen könnte. Dieses Risiko variiert je nach Art des Programms, das als Multithread-Programm codiert wird, kann jedoch erheblich sein. Dennoch überwiegen die Vorteile der Erstellung eines Multithread-Programms im Allgemeinen die Risiken.

Wie kompliziert ist Multithreading in Python?

Multithreading in Python

Es gibt noch einen weiteren Faktor, der alle Programmierer davon abhält, Multithread-Programme in einer beliebigen Sprache ihrer Wahl zu erstellen. Ganz einfach: Multithread-Programme sind schwierig zu programmieren und für Anfänger nicht zu empfehlen. Das Codieren von Multithread-Programmen erfordert Speicherverwaltungstechniken, die je nach der vom Programmierer verwendeten Programmiersprache als kontraintuitiv angesehen werden können.

In Python gibt es beispielsweise zwei Möglichkeiten, Threads in einem Programm zu erstellen. Der erste Weg, das -Modul, ist etwas älter und wird in modernen Versionen von Python nicht oft verwendet. Es ist jedoch in Legacy-Code beliebt und sollte daher dennoch von einem Programmierer studiert werden, der Multithreading wirklich verstehen möchte. Das Modul wird als Funktion behandelt und in modernen Versionen von Python als Modul <_thread> bezeichnet.

Die meisten modernen Python-Programme verwenden jedoch das -Modul, das oberflächlich dem -Modul ähnelt, tatsächlich aber deutlich mehr Flexibilität bietet als das -Modul. Das -Modul kann wie das -Modul einen funktionsbasierten Ansatz verwenden, kann aber auch einen objektorientierten Ansatz für Multithreading verfolgen, was weitaus einfacher ist. Der Anfänger eines Python-Threads stößt also bereits auf eine Situation, die knifflig sein kann – nämlich zwei verschiedene Module mit ähnlichen Namen, aber je nach Programmierung unterschiedlichen Herangehensweisen.

Entscheidet sich der Programmierer für die Verwendung des -Moduls, um eine Multithread-Anwendung zu erstellen, muss laut techbeamers.com zunächst eine Methode erstellt werden. Das von techbeamers bereitgestellte Beispiel ist „thread.start_new_thread ( function, args[, kwargs] )“, ohne Anführungszeichen. Wenn der Programmierer mit Methoden vertraut ist, wie sie in JavaScript oder vielen anderen Sprachen verwendet werden, sollte ihm diese Syntax bekannt vorkommen. Die Methode startet einen neuen Thread und gibt seinen Bezeichner zurück.

Beim Erstellen eines Threads basierend auf einem objektorientierten Ansatz verwendet das -Modul eine völlig andere Syntax als die Threading-Struktur. Entsprechend techbeamers.combesteht die erste Aufgabe, die der Programmierer erledigen muss, um Multithreading im Threading-Modul zu verwenden, darin, eine Unterklasse aus < zu erstellenFaden> Klasse. Dann muss der Codierer das < überschreiben__init__(self [,args])> Methode zur Bereitstellung von Argumenten. Schließlich muss der Codierer dann das < überschreibenlaufen(selbst [,args])> Methode zum Codieren der Geschäftslogik des Threads.

Nachdem die Threads erstellt wurden, muss der Programmierer eine Art Speicherverwaltung verwenden, um sicherzustellen, dass keine Konflikte zwischen Threads entstehen. Konflikte zwischen Threads (bei denen zwei Threads um denselben Speicherplatz konkurrieren) können zu Deadlocks führen, einer Situation, in der zwei oder mehr Prozesse auf dieselben Ressourcen warten und keiner voranschreiten kann, bis der andere nachgibt. Diese Situation kann zu erheblichen Leistungseinbußen führen und je nach Situation sogar dazu führen, dass eine Anwendung „einfriert“ oder abstürzt.

Glücklicherweise verfügt das Python--Modul über einige Funktionen, um das Auftreten dieser Situation zu verhindern, insbesondere die Lock()-Methode. Nach Verwendung der Lock()-Methode kann der Programmierer die Acquire(Blocking)-Methode aufrufen, die Threads zur synchronen Ausführung zwingt. Bei der Synchronisierung handelt es sich um den Vorgang, bei dem der Programmierer den Programmablauf steuern und dem Programm den Zugriff auf gemeinsam genutzte Daten ermöglichen kann. Mit anderen Worten: Durch die Synchronisierung kann der Programmierer entscheiden, welche Threads Priorität haben, wann Threads auf den Speicher zugreifen können und Threads sogar anweisen, zu warten, bis eine bestimmte Bedingung erfüllt ist. Dies wird natürlich dazu beitragen, Konflikte auf ein Minimum zu reduzieren.

Leider verfügt das Python--Modul nicht über eine solche Funktionalität, obwohl bestimmte Programmiertechniken dem erfahrenen Programmierer bei der Arbeit mit dieser Methode behilflich sein können. Eine Anleitung zur genauen Arbeit mit Multithreading mithilfe des Python-Moduls würde den Rahmen dieses Artikels sprengen. Wie aus den oben genannten Informationen hervorgeht, sollte das Codieren einer Multithread-Anwendung in Python nur von einem erfahrenen Programmierer versucht werden. Aber was ist mit anderen Programmiersprachen? Ist es einfacher, mit ihnen zu arbeiten?

Multithreading in Java

Multithreading in Java

Nehmen wir Java als Beispiel. Java ist für seine Multithreading-Fähigkeiten bekannt und existiert schon so lange, dass Bibliotheken für nahezu jede Situation erstellt werden konnten, mit der ein Programmierer konfrontiert werden kann. Laut Tutorialspoint.com sollte der Programmierer die folgenden Schritte ausführen, um ein Java-Programm zu programmieren, das Multithread-Prozesse ausführen kann.

Als ersten Schritt muss der Programmierer eine run()-Methode implementieren, die von einer ausführbaren Schnittstelle bereitgestellt wird. Dadurch wird eine Ausgangsbasis für die ordnungsgemäße Ausführung des Programms geschaffen. Der zweite Schritt wäre die Instanziierung eines Thread-Objekts mit dem folgenden Konstruktor: −Thread(Runnable threadObj, String threadName). Sobald das Thread-Objekt schließlich erstellt ist, kann der Programmierer es mithilfe der Start()-Methode starten. Dies ist eine Technik, die es dem Java-Programmierer ermöglicht, Multithread-Programme zu erstellen, wie auf Tutorialspoint.com beschrieben. Es gibt andere Möglichkeiten, Threads in der Java-Programmierung zu erstellen, und einige sind zugegebenermaßen einfacher – zum Beispiel kann der Java-Programmierer Threads einfach erstellen, indem er eine Thread-Klasse erweitert, was es dem Programmierer ermöglicht, mehrere Threads gleichzeitig zu erstellen.

Das Erlernen des Codierens von Multithread-Programmen hat einen unbestreitbaren Vorteil. Bei richtiger Programmierung führen Multithread-Programme Aufgaben schneller und effizienter aus als Single-Thread-Programme. Es kann jedoch nicht glaubhaft geleugnet werden, dass die Erstellung von Multithread-Programmen eine Herausforderung ist, die sich vor allem für erfahrene Programmierer eignet. Obwohl es verlockend sein mag, als Anfänger mit dem Codieren von Multithread-Programmen zu beginnen, ist es sinnvoll, mit einem derart komplizierten Projekt zu warten. Obwohl die Leistungssteigerungen erheblich sind, ist die Wahrscheinlichkeit hoch, dass Sie beim Programmieren frustriert werden und möglicherweise sogar Ihren Computer einfrieren. Das Codieren eines Multithread-Programms ist eine Aufgabe, die am besten erfahrenen Programmierern überlassen wird.

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Nach oben scrollen