Kann Multithreading auf einem Einzelprozessorsystem implementiert werden?

Lesezeit: 10 Minuten

Ich bin immer dem Konzept gefolgt, dass Multithreading nur auf Systemen mit mehreren Prozessoren implementiert werden kann, bei denen jedem Thread mehr als ein Prozessor zugewiesen werden muss und jeder Thread gleichzeitig ausgeführt werden kann. In diesem Fall gibt es keine Planung, da jeder Thread separate Ressourcen hat, die alle ihm gewidmet sind. Aber ich habe kürzlich irgendwo gelesen, dass ich Multithreading auch auf einem Einzelprozessorsystem durchführen kann. Ist es richtig? und wenn ja, was ist dann der Unterschied zwischen Systemen mit einem Prozessor und mehreren Prozessoren?

  • Ja, und um es einfach auszudrücken, wahrgenommene vs. tatsächliche Parallelität.

    – WhozCraig

    20. April 2013 um 5:29 Uhr

  • Wenn es nicht möglich wäre, dann war Windows 95 eine Massenhalluzination. (Wenn Sie Multiprocessing als Multithreading zählen, dann war das ursprüngliche Unix auch eine Massenhalluzination.)

    – Raymond Chen

    20. April 2013 um 16:19 Uhr

  • https://stackoverflow.com/questions/16116952/can-multithreading-be-implemented-on-a-single-processor-system (qnx.com/developers/docs/qnxcar2/…) Bilder stärker als Worte

    – LinconFive

    15. Mai 2020 um 2:03 Uhr

Benutzeravatar von Barath Ravikumar
Barath Ravikumar

Ich habe kürzlich irgendwo gelesen, dass ich Multithreading auch auf einem Einzelprozessorsystem ausführen kann. Ist es richtig? und wenn ja, was ist dann der Unterschied zwischen Systemen mit einem Prozessor und mehreren Prozessoren?

Ja, Sie können Multithreading auf einem Einzelprozessorsystem durchführen.

In Mehrprozessorsystemen werden mehrere Threads ausgeführt, gleichzeitig auf verschiedenen Kernen. Beispiel: Wenn zwei Threads und zwei Kerne vorhanden sind, wird jeder Thread auf einem einzelnen Kern ausgeführt.

In einem Einzelprozessorsystem werden mehrere Threads nacheinander ausgeführt oder warten, bis ein Thread beendet oder vom Betriebssystem unterbrochen wird, abhängig von der Thread-Priorität und der Betriebssystemrichtlinie. Aber die laufenden Threads erwecken die Illusion, dass sie gleichzeitig ausgeführt werden , relativ zur erforderlichen Reaktionszeit der Anwendung der Benutzerbereichsanwendung.

Zeitvergleich (Beispiel):

Wenn zwei Threads jeweils 10 us für die Ausführung benötigen, beträgt die Nettozeit auf einem 2-Prozessor-System 10 us

Wenn zwei Threads jeweils 10 us für die Ausführung benötigen, beträgt die Nettozeit auf einem 1-Prozessor-System 20 us

  • sehr hilfreich. Vielen Dank 🙂

    – Ayse

    20. April 2013 um 5:46 Uhr

  • Chrome führt Tabs aus Prozesse, keine Fäden. Die Behauptung, dass Threads die Stabilität verbessern, ist falsch. Es ist nicht möglich, dass ein Thread abstürzt und den Rest laufen lässt. Da sich alle Threads eines Prozesses einen gemeinsamen Adressraum teilen, sind sie möglicherweise alle von einem Thread betroffen, der den Speicher überlastet. Darüber hinaus beendet eine unfreiwillige Beendigung, die durch einen “Absturz” eines Threads verursacht wird, den gesamten Prozess, nicht nur einen einzelnen Thread.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    20. April 2013 um 5:54 Uhr

  • @R .. Ok, ich habe den kontroversen Teil entfernt … vielleicht habe ich nicht genug gelesen, um die Stabilität von Threads zu sichern und zu rechtfertigen …

    – Barath Ravikumar

    20. April 2013 um 6:01 Uhr

  • Die einzige Möglichkeit, ein Argument dafür zu sehen, dass Threads “die Stabilität verbessern”, besteht darin, den Code zu vereinfachen und Fehler weniger wahrscheinlich zu machen. Es ist viel einfacher, synchrone Logik zu schreiben, die in einem eigenen Thread läuft, als asynchrone, ereignisgesteuerte Zustandsmaschinenlogik, und dies könnte zu sichereren, stabileren Programmen führen. Threads geben Ihnen jedoch keine Sicherheit, wenn einer von ihnen UB aufruft.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    20. April 2013 um 6:04 Uhr

  • Ich denke, BarathBushans Antwort ist hilfreich und die Leute sollten es vermeiden, sie abzulehnen 🙁

    – Ayse

    20. April 2013 um 6:22 Uhr


Natürlich geht das auch auf einem Einprozessorsystem, und tatsächlich ist es so viel einfacher. Es funktioniert genauso wie das Ausführen mehrerer Prozesse – der Kernel hält über einen Timer-Interrupt oder einen ähnlichen Mechanismus einen an, speichert seinen Maschinenzustand und ersetzt diesen durch den zuvor gespeicherten Zustand eines anderen – der einzige Unterschied sind diese beiden Threads desselben Prozesses teilen sich denselben virtuellen Speicherplatz, wodurch der Task-Wechsel viel effizienter wird.

Multi-Threading auf Mehrprozessorsystemen ist tatsächlich viel schwieriger, da Sie Probleme mit dem gleichzeitigen Zugriff auf den Speicher von mehreren CPUs/Kernen und all den unangenehmen Problemen mit der Speichersynchronisierung haben, die sich daraus ergeben.

  • Ich danke dir sehr. Das war hilfreich

    – Ayse

    20. April 2013 um 5:45 Uhr

  • Nein, das müssen Sie falsch verstehen, denn die Aussage, wie Sie sie paraphrasiert haben, ist definitiv falsch.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    20. April 2013 um 12:37 Uhr

  • ⁺¹ für den «Timer-Interrupt». Whole Internet erwähnt nicht, wie genau die Umschaltung in Hardware erfolgt; Ich nahm an, dass es sich um eine Art Timer handelt, aber selbst die Wikipedia schweigt.

    – Hallo Engel

    10. März 2016 um 13:48 Uhr

  • Wenn 2 Threads auf einem Prozessor laufen … ist keine Synchronisierung erforderlich?

    Benutzer2156081

    24. Dezember 2016 um 20:23 Uhr

  • Habe die Antwort von @Barath post bekommen.

    Benutzer2156081

    24. Dezember 2016 um 20:27 Uhr

Auf einem Quad-Core-System können mehr als vier aktive Threads vorhanden sein. Dort ist Scheduling, es sei denn, Sie können garantieren, dass Prozesse nicht versuchen, mehr Threads zu erstellen, als Prozessoren vorhanden sind.

Ja, Sie können mehrere Threads auf einem Single-Core-Computer haben.

Der Unterschied zwischen Einprozessor- und Mehrprozessorsystemen besteht darin, dass ein Mehrprozessorsystem tatsächlich mehr als eine Sache gleichzeitig erledigen kann. Es kann N Dinge gleichzeitig tun, wobei N die Anzahl der Prozessorkerne ist. Ein Single-Prozessor-Kern kann nur eine Sache gleichzeitig tun. Wie WhozCraig in seinem Kommentar sagte, ist es der Unterschied zwischen tatsächlicher und wahrgenommener Parallelität.

  • Vielen Dank, ich habe jetzt die Grundidee, wie die Dinge gemacht werden

    – Ayse

    20. April 2013 um 5:45 Uhr

Ja, das kannst du absolut. Vor Ewigkeiten (Win 95?) sind wir von kooperativem Multitasking auf Multithreading umgestiegen, weil immer jemand den kooperativen Teil vermasselt hat. Jedes Programm auf Ihrem Computer hat mindestens einen Thread. Möglicherweise mehr. Und die CPU wechselt wie verrückt ein paar Millionen Mal pro Sekunde zwischen all diesen Threads. Wenn keiner von ihnen etwas zu tun hat, kann es sogar sein, dass es einige Zeit stillsteht.

Multicore-Systeme bedeuten nur, dass zwei oder mehr dieser Threads parallel laufen können.

Allerdings bringt es Ihnen viel weniger, dies zu tun. Alles, was Sie mit Multithreading auf einem Single-Core-Computer tun können, ist Multitasking zu simulieren.

Multitasking reicht aus, um zu verhindern, dass der GUI-Thread aufgrund einer lang andauernden Operation blockiert. Es ist jedoch im Allgemeinen kompliziert zu implementieren, es sei denn, Sie haben Hilfe vom Compiler oder der Sprache (wie C # async … warten). Infolgedessen verwendeten viele GUI-Programmierer nur Multithreading und Invoking, um Multitasking vorzutäuschen. Ob dieser Code auf einem oder mehreren Kernen läuft, spielt keine Rolle.

Am wichtigsten ist, dass Multitasking NICHT für CPU-gebundene Operationen geeignet ist. Aber 95 % aller Async-Probleme sind nicht CPU-gebunden. Sie sind netzwerk- oder festplattengebunden. Auf einem Singlecore-Computer hilft Multithreading auch nicht bei CPU-gebundenen Dingen. Wenn Sie zwei Threads haben, die beide 100 % CPU-Zeit benötigen (dasselbe Programm oder ein anderes), aber nur einen Kern, um sie auszuführen, muss die CPU nur zwischen der Ausführung beider mit 49 % wechseln und die verbleibenden 2 % für all diese verwenden andere Threads, die nur ein bisschen tun.

Schließlich können nur sehr wenige Probleme tatsächlich Multithreaded werden. Versuchen Sie einfach, die Fibonacci-Folge zu multithreaden (ein Thread für jedes Paar), ohne sie langsamer, speicherintensiver und komplexer zu machen.

tl;dr; Sie benötigen Multithreading und einen Multicore-Computer für CPU-gebundene Probleme. Die meisten asynchronen Probleme sind nicht CPU-gebunden. Multitasking reicht völlig aus. Und Sie können mithilfe von Threads vollständig multitasken, sogar auf einem Computer mit einem Kern.

Benutzeravatar von luser droog
Luser Drog

Hier ist ein sehr vereinfachtes Beispiel. Es ist eigentlich ein Prototyp für ein Programm, das ich baue. Es ist eine Implementierung von kooperativem Multitasking in einem einzigen Thread.

main setzt einfach die quit Flag auf false und füllt ein Array von Funktionszeigern (die Aufgaben) und ruft dann auf loop.

loop Verwendet setjmp um einen Rückkehrpunkt für einen nicht-lokalen Sprung zu setzen (ein jump aus der Funktion zurück zu einer vorherigen Position in der Ausführung) und fährt dann fort, die erste Aufgabe (Funktion) aufzurufen.

Jede Aufgabe endet mit yield(). Das heißt, keine der Aufgaben funktioniert tatsächlich return. Sie enthalten nicht nur keine a return; Aussage (was in Ordnung wäre, da sie es sind void Funktionen, dh. Verfahren), aber sie würden die nicht erreichen return auch wenn es da war yield springt zurück zum setjmp Anruf, diesmal mit einer 1 für die if Aussage ein loop. Die Anweisung, die von der gesteuert wird if Anweisung wählt eine andere Aufgabe aus, bevor Sie die erneut eingeben while Schleife.

Jede Task-Funktion wird also mehrmals ausgeführt, was zu dem führt Dispatcher (das if(setjmp... -Anweisung), die eine neue auszuführende Aufgabe auswählt.

#include <stdio.h> 
#include <setjmp.h> 

jmp_buf dispatch; 
int ntasks; 
void (*task[10])(void); 
int quit; 

void yield(void) { 
    longjmp(dispatch, 1); 
} 

void loop() { 
    static int i = 0; 
    if(setjmp(dispatch)) 
        i = (i+1) % ntasks; 
    while(!quit) 
        task[i](); 
} 

int acc = 0; 

void a(void) { 
    if (acc > 10) quit = 1; 
    printf("A\n"); 
    yield(); 
} 
void b(void) { 
    acc *= 2; 
    printf("B\n"); 
    yield(); 
} 
void c(void) { 
    acc += 1; 
    printf("C\n"); 
    yield(); 
} 

int main() { 
    quit = 0; 
    ntasks = 3; 
    task[0] = a; 
    task[1] = b; 
    task[2] = c; 
    loop(); 
    return 0; 
} 

Der Unterschied zwischen diesem Beispiel und einem Einzelprozessor-Multitasking-Computersystem besteht darin, dass der reale Prozessor das Unterbrechen einer Aufgabe mitten in der Ausführung und deren spätere Wiederaufnahme an derselben Stelle unterstützt. Dies ist in einer C-Simulation mit Aufgaben als einzelne Funktionen nicht wirklich möglich. Die Tasks könnten jedoch aus einer Folge von C-Funktionen bestehen, die jeweils an den Dispatcher übergeben werden (vielleicht ein Array von Funktionszeigern oder eine verkettete Liste).

  • Können Sie bitte eine Art Beschreibung oder Kommentar hinzufügen, um genau zu erklären, was dies zeigen und tun soll? Vielen Dank.

    – Deanna

    26. April 2013 um 12:52 Uhr

  • Mit einigen Erläuterungen bearbeitet. (Bei Bedarf kann ich weitere hinzufügen.)

    – Luser Drog

    26. April 2013 um 13:10 Uhr

  • Es sieht nicht so aus, als gäbe es eine Möglichkeit, von a zurückzukehren yield(), also muss jeder Thread abgeschlossen werden, bevor er yield aufruft. Es gibt also keine Möglichkeit, mehr als einen Live-Thread gleichzeitig zu haben und zwischen ihnen zu wechseln. Sie könnten die Dinge also viel einfacher machen, indem Sie die Aufgaben einfach zurückgeben (anstatt yield aufzurufen) und nicht verwenden setjmp/longjmp überhaupt.

    – Chris Dodd

    20. September 2013 um 1:07 Uhr


Benutzeravatar von Neethu Lalitha
Neethu Lalitha

In einem Multithread-Prozess auf einem einzelnen Prozessor kann der Prozessor Ausführungsressourcen zwischen Threads wechseln, was zu einer gleichzeitigen Ausführung führt. Parallelität gibt an, dass mehr als ein Thread Fortschritte macht, die Threads jedoch nicht gleichzeitig ausgeführt werden. Das Umschalten zwischen Threads erfolgt schnell genug, dass die Threads scheinbar gleichzeitig ausgeführt werden.

In demselben Multithread-Prozess in einer Mehrprozessorumgebung mit gemeinsam genutztem Speicher kann jeder Thread im Prozess gleichzeitig auf einem separaten Prozessor ausgeführt werden, was zu einer parallelen Ausführung führt, die eine echte simultane Ausführung ist. Wenn die Anzahl der Threads in einem Prozess kleiner oder gleich der Anzahl der verfügbaren Prozessoren ist, stellt das Thread-Unterstützungssystem des Betriebssystems sicher, dass jeder Thread auf einem anderen Prozessor ausgeführt wird. Beispielsweise kann bei einer Matrixmultiplikation, die mit vier Threads programmiert ist und auf einem System mit zwei Dual-Core-Prozessoren läuft, jeder Software-Thread gleichzeitig auf den vier Prozessorkernen laufen, um gleichzeitig eine Reihe des Ergebnisses zu berechnen.

  • Können Sie bitte eine Art Beschreibung oder Kommentar hinzufügen, um genau zu erklären, was dies zeigen und tun soll? Vielen Dank.

    – Deanna

    26. April 2013 um 12:52 Uhr

  • Mit einigen Erläuterungen bearbeitet. (Bei Bedarf kann ich weitere hinzufügen.)

    – Luser Drog

    26. April 2013 um 13:10 Uhr

  • Es sieht nicht so aus, als gäbe es eine Möglichkeit, von a zurückzukehren yield(), also muss jeder Thread abgeschlossen werden, bevor er yield aufruft. Es gibt also keine Möglichkeit, mehr als einen Live-Thread gleichzeitig zu haben und zwischen ihnen zu wechseln. Sie könnten die Dinge also viel einfacher machen, indem Sie die Aufgaben einfach zurückgeben (anstatt yield aufzurufen) und nicht verwenden setjmp/longjmp überhaupt.

    – Chris Dodd

    20. September 2013 um 1:07 Uhr


1419750cookie-checkKann Multithreading auf einem Einzelprozessorsystem implementiert werden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy