Konzeptionell ist ein Programm ein einzelner Thread, der mehrere serielle Aufgaben ausführt, eine nacheinander.
Die C -Sprache ermöglicht es uns, Multithread -Programme mit der PThread -Bibliothek des POSIX -Standards zu schreiben.
Ein Multi-Thread-Programm ist ein Thread oder eine Aufgabe, die parallel und gleichzeitig mit dem Hauptprogramm und anderen Threads ausgeführt wird, die in einem Teil davon nach demselben Programm eröffnet werden.
In diesem Linux -Hinweis In Artikel lernen Sie, wie Sie einen Thread aus einem Hauptprogramm mit dem erstellen pthread_create () Funktion der PThread -Bibliothek.
Dies erläutert die theoretischen Arbeitsweise dieser Funktion, ihre Syntax-, Eingabe- und Ausgabemargumente und den in jedem Fall akzeptierten Datentyp.
Wir werden dann das, was wir in praktischen Beispielen gelernt haben.
Syntax der Funktion pThread_create () in der C -Sprache
int pthread_create (pthread_t *Thread einschränken,Beschreibung der Funktion pThread_create () in der C -Sprache
Der pthread_create () Die Funktion erstellt einen Thread und führt ihn parallel und gleichzeitig mit dem Programm aus, das es erstellt hat. Diese Funktion führt die von ihrem Zeiger in der Eingabe angegebene Routine aus start_routine durch Übergabe des Eingabebuchs arg.
Lassen Sie uns als Nächst pthread_create () Im Detail sowie eine Beschreibung der Arbeit, die jede dieser Argumente innerhalb der Funktion erbringt.
Gewinde: Dies ist ein Ausgabeargument, das die Kennung des erstellten Threads zurückgibt. Diese Kennung wird verwendet, um sie in bestimmten Thread -Verwaltungsfunktionen wie pthread_join () oder pthread_cancel () zu verweisen.
Attr: Dieser Eintrag ist der Zeiger auf eine Struktur vom Typ pthread_attr_t, dessen Mitglieder die Attribute des neuen Threads angeben. Wenn dieses Argument an Null gesendet wird, werden die Attribute des neuen Threads mit ihren Standardparametern aufgenommen.
start_routine: Dies ist der Zeiger auf die Funktion, die vom neuen Thread ausgeführt wird.
arg: Dies ist der Zeiger auf das Argument, dass die Hauptfunktion an den neuen Thread übergeht.
Wenn der Thread erfolgreich erstellt wird, pthread_create () Gibt 0 als Ergebnis zurück. Wenn ein Fehler auftritt, gibt er -1 zurück und speichert in der globalen Variablen Errno Der spezifische numerische Wert, der diesen Fehler darstellt.
Der pthread_create () Die Funktion ist im PThread definiert.H Kopfball. Um es zu verwenden, müssen die folgenden Header in die “enthalten sein.c ”Datei, wie unten gezeigt:
#enthaltenKompilierungsfehler in Programmen mit Threads
Wenn Sie GCC -Programme kompilieren, die Threads verwenden.
Die häufigste Fehlermeldung des Compiler gibt an, dass eine der Thread -Funktionen, auf die wir im Code verweisen.
Diese Fehler führen häufig dazu, wertvolle Zeit zu verschwenden, um die Header zu überprüfen, die wir in den Code eingefügt haben, deren Integrität und mit dem Compiler verbundenen Verzeichnisse.
Obwohl die Funktionen, die den Fehler verursachen.H ”Header und in den Code aufgenommen. Der Compiler erkennt diese Funktionen nicht, es sei denn.
Im Folgenden können Sie in Grün die richtige Art und Weise sehen, wie die PThread -Bibliothek während der Zusammenstellung von Programmen mit Threads aus der Befehlskonsole aufgerufen wird:
~ $ GCC -PTHEAD PATH/Dateiname.c -o out_nameWie in der folgenden Abbildung gezeigt, verschwindet der Fehler, wenn die PThread -Bibliothek während der Zusammenstellung aufgerufen wird.
So erstellen und ausführen
In diesem Beispiel werden wir erklären, wie pthread_create () Arbeiten. Dazu erstellen wir eine Hauptfunktion und öffnen Sie einen Thread, der die ausführt thread_function () parallel zu dem funktionieren Hauptfunktion.
Der Code für dieses Beispiel besteht aus zwei Abschnitten, der hauptsächlich() Funktion und die thread_function () Funktion, das ist der Thread.
Als nächstes erklären wir jede der beiden Funktionen separat und setzen sie dann zusammen, um den Code zu kompilieren und auszuführen.
thread_function (): Diese Funktion besteht aus a für Schleife mit 5 Zyklen, in denen die Meldung „aus dem Thread“ in der Befehlskonsole angezeigt wird, und nach einer Verzögerung von 3 Sekunden wird der Zyklus erneut wiederholt. Die Nachricht dieser Funktion ist mit der der der des hauptsächlich() Funktion so, dass Sie in Echtzeit sehen können, was jeder der Prozesse gleichzeitig funktioniert.
Als nächstes sehen wir die Nclusi die thread_function () Funktion und die Definition seines Prototyps:
void* thread_function (void* n);Hauptfunktion: In diesem Beispiel die hauptsächlich() Funktion ist nclusióne zum Definieren der Variablen und zum Erstellen des Threads.
Der erste Schritt beim Erstellen eines Threads besteht darin, eine Variable des Typs zu definieren pthread_t Diese NCL dient als Kennung des Threads. In diesem Beispiel nennen wir diese Variable ncle Thread_1.
Um den Thread zu nclus, nennen wir das pthread_create () Funktion und übergeben Sie den Thread Identifier Thread_1 als erstes Argument.
Die Attribute des zu erstellenden Threads sind in diesem Fall voreingestellt, sodass das zweite Eingabemargument null ist.
Als drittes Argument geben wir den Zeiger in die Funktion, die in diesem Fall im neuen Thread ausgeführt werden soll thread_function ().
Da wir in diesem Beispiel keine Argumente an den neuen Thread weitergeben müssen, ist der Arg -Zeiger NCL auch null.
Nach dem Anruf pthread_create (), Der neue Thread beginnt die Ausführung und die Funktion hauptsächlich() tritt ein für Schleife mit 5 Zyklen, von denen jede die Meldung „Aus Hauptfunktion“ druckt, die mit der Nachricht „aus dem Thread“ der Funktion verschachtelt ist thread_function (). Nach jeder Nachricht wird eine Verzögerung von 3 Sekunden in die für Schleifen beider Funktionen eingefügt, bevor ein neuer Zyklus gestartet wird.
Im Folgenden sehen Sie die Nclusi die Funktion hauptsächlich(), die nclusión der notwendigen Header und die Erklärung des Prototyps der Funktion thread_function ():
#enthaltenAls nächstes sehen wir den vollständigen Code für dieses Beispiel. Kopieren Sie dieses Fragment und fügen Sie in eine Datei mit einer "ein" ein ".C ”Erweiterung. Kompilieren Sie den Code und führen Sie ihn aus, um zu sehen, wie die hauptsächlich() Funktion und der neue Thread führen ihre Aufgaben gleichzeitig aus.
#enthaltenDas Bild, das wir unten sehen, zeigt die Aufgabe, die der Thread mit dem erstellt wurde pthread_create () parallel zur Aufgabe der Funktion der hauptsächlich() Funktion, und die Nachrichten, die jeweils an die Befehlskonsole gesendet werden:
Synchronisation von Threads in der C -Sprache
Im Code des vorherigen Beispiels ist die Ausführungszeit des Threads kürzer als die des hauptsächlich() Funktion und deshalb machen beide ihre Arbeit richtig. Dies ist auf die Verzögerung von 3 Sekunden zurückzuführen, die auftritt, wenn die hauptsächlich() Funktion verlässt die Schleife.
Wenn die Ausführungszeiten eines Threads jedoch länger sind als die der der der hauptsächlich() Funktion und es ist vollständig ausgeführt, das Programm endet und alle erstellten Themen, die erstellt wurden und immer noch eine Aufgabe ausführen, werden automatisch geschlossen.
Lassen Sie uns sehen, was im Code des vorherigen Beispiels passiert, wenn wir eine Verzögerung von 1 Sekunde pro Zyklus in der für die Schleife des hauptsächlich() Funktion und eine von 3 Sekunden in der Thread -Schleife.
Wie im Bild gezeigt, die hauptsächlich() Die Funktion beendete die 5 Zyklen von IES für Schleife, während der Thread nur 3 Zyklen ausführen konnte, bevor das Programm geschlossen wurde.
Schließen eines Thread.
Um diese Probleme zu vermeiden, ist es wichtig, einen Mechanismus zu entwickeln, um zu „warten“, damit der Thread die Ausführung abschließt, bevor das Programm schließt oder eine Aufgabe ausführt. Der pthread_join () Funktion stoppt die Funktion, die den Thread erstellt hat, bis dieser Thread seine Ausführung beendet hat.
Der pthread_join () Funktion nimmt zwei Eingabeargumente an. Der erste ist der von der zurückgegebene Thread -Kennung pthread_create () Funktion Wenn der Thread erstellt wird und das zweite Argument der Zeiger auf eine Variable ist, die den Exit -Status des Threads zurückgibt.
Als nächstes verwenden wir den Code aus dem vorherigen Beispiel, ersetzen aber die für Schleife der hauptsächlich() Funktion mit dem pthread_join () Funktion, wie unten gezeigt:
#enthaltenIn diesem Fall die hauptsächlich() Die Funktion erstellt einfach den Thread und wartet, bis er seine Aufgabe beendet hat, und schließt dann das Programm.
Mögliche Fehler, die die Funktion pThread_create () erzeugen kann und wie sie erkannt werden können
Der pthread_create () Funktion kann verschiedene Fehler generieren, von ungültigen Attributeinstellungen bis hin zu unzureichenden Systemressourcen für den neuen Thread.
Wenn eine Funktion einen Fehler generiert, wird in der globalen Variablen ein numerischer Fehleridentifikationscode gespeichert Errno. Diese Variable und die numerischen Definitionen für jeden Fehler sind im „Errno.H ”Kopfball.
Unten finden Sie eine Beschreibung jedes Fehlers, der beim Aufrufen der pthread_create () Funktion und ihre numerische Darstellung in „Errno definiert.H".
Eagain: Es stehen keine Ressourcen zur Verfügung, um einen anderen Thread zu erstellen. Die numerische Darstellung dieses Fehlers beträgt 35.
Einval: Die Attributkonfiguration in ATT ist nicht gültig. Die numerische Darstellung dieses Fehlers beträgt 22.
Eperm: Betrieb nicht erlaubt. Dieser Fehler tritt auf, wenn Sie nicht über ausreichende Berechtigungen verfügen, um die Attributparameter in Attr zu setzen. Die numerische Darstellung dieses Fehlers beträgt 1.
Abschluss
In diesem Linux -Hinweis Artikel, wir haben Ihnen gezeigt, wie man das benutzt pthread_create () Funktion zum Erstellen von Multitasking -Programmen mit Threads, die parallel zur Hauptfunktion ausgeführt werden.
Wir haben Ihnen auch gesagt, wie Sie Programme kompilieren, die Threads korrekt aus der Befehlszeile verwenden.
Wir haben auch einen speziellen Abschnitt beigefügt, in dem die Bedeutung der Ausführungszeiten der erstellten Threads wichtig ist, und wir haben Ihnen beigebracht, wie Sie die Threads mit der Hauptfunktion synchronisieren können, um ihre korrekte Ausführung zu erreichen.