Wie man einen Thread in C erstellt, ohne die POSIX-Bibliothek zu verwenden [closed]

Lesezeit: 5 Minuten

Ich möchte das multiple Threading in C implementieren, ohne die POSIX-Bibliothek zu verwenden. Jede Hilfe wäre willkommen.

Nicht : Fork() oder vfork() nicht verwenden.

  • Sie müssen eine Bibliothek verwenden, die das tut. Threading ist ein OS-Baustein. Sie können sie nicht selbst mit einem Programm erstellen. Dennoch können Sie Dinge wie glibc verwenden, die eine API zum Ausführen bestimmter Aufgaben als separaten Thread bereitstellt

    – fkl

    8. November 2012 um 5:55 Uhr

  • Sie müssen eine Bibliothek verwenden, die Threads für Sie erstellt. Alternativen für pthreads finden Sie hier gnu.org/software/pth/related.html

    – CCoder

    8. November 2012 um 5:59 Uhr

  • Gibt es einige real Warum möchten Sie keine POSIX-Threads verwenden? Sofern Sie keinen triftigen Grund haben, sollten Sie sie verwenden und keine Zeit mehr verschwenden (Ihre und unsere).

    – paxdiablo

    8. November 2012 um 6:04 Uhr

  • @paxdiablo Diese Frage wurde mir in einer letzten Runde einer technischen Veranstaltung gestellt, und dies war die Frage mit der höchsten Punktzahl. Ich hätte gewonnen, wenn ich die Antwort gewusst hätte. und ich verwende POSIX-Threads in REAL World.

    – Raul

    8. November 2012 um 6:12 Uhr

  • @RahulKumar Überprüfen Sie meine aktualisierte Antwort. Der Vollständigkeit halber habe ich auch Threads auf Benutzerebene erwähnt.

    – iabdalkader

    8. November 2012 um 7:07 Uhr

Benutzeravatar von iabdalkader
iabdalkader

Ein Thread in Linux ist im Wesentlichen ein Prozess, der Anteile Speicher und Ressourcen mit seinem übergeordneten Element. Der Linux-Kernel tut es nicht zwischen einem Prozess und einem Thread unterscheiden, mit anderen Worten, es gibt kein Konzept von a Leicht Prozess in Linux wie in einigen anderen Betriebssystemen. Threads in Linux sind implementiert als Standard Prozesse, sodass es möglich ist, einen Thread mit nur zu erstellen clone() die normalerweise von angerufen wird fork() auf die folgende Weise:

clone(SIGCHLD, 0);

Dies klont nur die Signalhandler, aber mit den entsprechenden Flags können Sie einen Thread erstellen:

clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0);

Dies ist identisch mit dem vorherigen Aufruf, außer dass der Adressraum, Dateisystemressourcen, Dateideskriptoren und Signalhandler sind geteilt durch die beiden Prozesse.

Ein anderer Ansatz ist zu verwenden Threads auf Benutzerebene (auch Fasern genannt) Dies sind Ausführungsthreads, die auf Benutzerebene implementiert sind, was bedeutet, dass das Betriebssystem diese Threads und die Planung nicht kennt oder Kontextwechsel muss auf Benutzerebene erfolgen. Die meisten Scheduler auf Benutzerebene sind als kooperative Scheduler implementiert, aber es ist auch möglich, einen präemptiven Scheduler mit einem einfachen zu implementieren Round-Robin-Planung.

Überprüf den Klon(2) Manpage für Details und wenn Sie weitere Informationen wünschen, empfehle ich die Linux Kernel Development 3rd Edition Von Robert Love, (in keiner Weise mit dem Autor verbunden) Es gibt einen Link zum Blick ins Innere, dort können Sie einiges davon online lesen. Was die Threads auf Benutzerebene betrifft, so gibt es ein von mir geschriebenes Minimalpaket mit dem Namen fragendas sowohl einen kooperativen als auch einen präemptiven Scheduler implementiert, können Sie den Quellcode überprüfen, wenn Sie möchten.

Anmerkung 1: Ich habe UNIX nicht erwähnt, soweit ich weiß, ist dies eine Linux-spezifische Implementierung.

Hinweis 2: Das Erstellen eigener Threads mit Clone ist keine reale Lösung. Lesen Sie die Kommentare zu einigen Problemen, mit denen Sie sich möglicherweise befassen müssen. Es ist nur eine Antwort auf die Frage, ob es möglich ist, Threads ohne die Verwendung von pthreads zu erstellen, in diesem Fall die Antwort ist ja.

  • Wahrscheinlich möchten Sie einen Stack für den geklonten Prozess vorbereiten. Oh, und verwenden Sie keine Bibliotheksfunktionen im untergeordneten Thread, da Ihr TLS-Setup komplett vermasselt wird.

    – bdonlan

    8. November 2012 um 6:13 Uhr

  • “Eigene Threads erstellen” mit clone wird nicht funktionieren es sei denn, Sie verzichten auf (direkte oder indirekte) Aufrufe der Standardbibliothek. Dies liegt daran, dass selbst so grundlegende Dinge wie Lesen / Schreiben errno Zugriff auf Thread-lokalen Speicher relativ zu einer Thread-Zeiger-/Thread-Deskriptor-Struktur, die nicht initialisiert wird oder auf etwas Gültiges zeigt, wenn Sie aufrufen clone du selbst.

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

    8. November 2012 um 7:40 Uhr

didiercs Benutzeravatar
didierc

Sehen:

für UNIX-ähnliche Systeme.

Siehe auch:

für BSDs und moderne UNIXes.

Das Buchseite gibt viele Beispiele für Barebone-Implementierungen, die diese Grundelemente und mehr verwenden.

Sie können atomare Anweisungen verwenden, um die Sperrprimitive (Mutex, Semaphore) zu implementieren.

Ich schlage auch vor, sich aktuelle Implementierungen von Userland-Thread-Bibliotheken anzusehen, um einige Hinweise zu erhalten. Sehen diese Seite die eine Liste von Implementierungen für Linux enthält.

Schließlich möchten Sie vielleicht einige Informationen über erhalten Koroutinen und vielleicht Trampolineobwohl letzteres nicht so eng verwandt ist.

  • Implementierung von Threads à la main using longjmp() ist ein sehr schlechter Rat.

    Benutzer529758

    8. November 2012 um 9:54 Uhr

  • @H2CO3 Ich sage nicht, dass es einfach ist 🙂

    – didierc

    8. November 2012 um 10:15 Uhr

  • @ H2CO3, aber es ist machbar, siehe den von mir bereitgestellten Link.

    – didierc

    8. November 2012 um 10:25 Uhr

  • Ich habe nicht darüber gesprochen, ob es leicht oder schwer ist (wenn Sie geschickt genug sind, ist alles einfach), ich sage, es ist schlechte Übung und man sollte es nicht tun.

    Benutzer529758

    8. November 2012 um 10:56 Uhr

  • @H2CO3 Könnten Sie erklären, warum dies eine schlechte Praxis ist? Es ist ein Thema und ich würde es gerne wissen!

    – didierc

    8. November 2012 um 12:03 Uhr

Sie können sich auch das Neue ansehen <threads.h> Header aus der C-Standardbibliothek. (C11)

Es hat, was Sie brauchen int thrd_create(thrd_t *thr, thrd_start_t func, void *arg); sowie Mutex-Funktionen und Bedingungsvariablen.

Benutzeravatar von Aki Suihkonen
Aki Suihkonen

Man kann mit ziemlicher Sicherheit zumindest einen kooperativen Mikrokernel mit einfachem c auf so ziemlich jedem Betriebssystem erstellen. Grundsätzlich erfordert es nur das Klonen des Stapelrahmens (und das entsprechende Anpassen einiger Zeiger – insbesondere der Rücksprungadresse von einer Funktion zur aktuellen Rücksprungadresse der anderen Threads). Und ein paar Hilfsfunktionen, wie z. B. “Kontextwechsel” vom Stack zum Heap und zurück.

Wenn ein Timer-Interrupt mit einem Callback erlaubt ist, kann man einen präemptiven Mikrokernel machen.

Zumindest haben Dr. Dobbs und IOCCC Optionen in diese Richtung vorgestellt.

1443900cookie-checkWie man einen Thread in C erstellt, ohne die POSIX-Bibliothek zu verwenden [closed]

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

Privacy policy