Welche Green-Threads-Bibliotheken sind für C verfügbar, die mit der Leistung und Benutzerfreundlichkeit der Green-Threads von Haskell mithalten können? [closed]

Lesezeit: 6 Minuten

Benutzer-Avatar
Cetin Sert

Ich bin es gewohnt, mich auf GHCs zu verlassen forkIO für portable leichte Threads beim Programmieren in Haskell.

Was sind äquivalente Bibliotheken für C, die die gleiche Skalierbarkeit und Benutzerfreundlichkeit bieten können?

Insbesondere benötige ich C-Äquivalente von mindestens den folgenden zwei Funktionen.

forkIO     :: IO () -> IO ThreadId
killThread ::             ThreadId -> IO ()

Ich gehe davon aus, dass es für meine Anwendung ausreichen würde, wenn Threads nur bei Blockierungsvorgängen eingeschaltet würden, anstatt zwangsweise suspendiert zu werden, da alle Threads sehr häufig für Netzwerk-IO blockieren und ich nur die nutze splice Systemaufruf, um den Linux-Kernel aufzufordern, Daten zwischen Sockets zu verschieben.


Aktualisieren

Dieses Papier hat Abbildungen und Tabellen zum Vergleich

mit Ergebnissen zugunsten von Protothreads. Da ich keine verwendet habe und es möglicherweise auch andere Bibliotheken gibt, würde ich gerne von jemandem hören, der solche Bibliotheken verwendet / entwickelt hat.

  • Wage ich sagen foreign export von libHSrts.a … ? (dh verwenden Sie einfach die GHC-Laufzeitumgebung, die schließlich eine C-Bibliothek ist). Allerdings beträgt die GHC-Laufzeit 50.000 Zeilen C und Verwendet epoll für die Threadplanung. Sie benötigen einen Epoll-Wrapper.

    – Don Stewart

    16. Januar 2013 um 21:48 Uhr


  • Zu Ihrer letzten Frage: Schreiben Sie korrekte Funktionsprototypen und verlinken Sie mit -lHSrts.

    – Christo Iljew

    16. Januar 2013 um 22:17 Uhr

  • @KenWhite Um fair zu sein, weist das OP auf Kriterien oder zumindest eine Eintrittsschwelle hin: die Leistung und Benutzerfreundlichkeit von Haskells grünen Fäden. Er fährt fort, Verweise auf bestimmte Haskell-Funktionen bereitzustellen, deren C-Äquivalente benötigt werden. Die Formulierung mag suboptimal sein, aber die Frage als Ganzes steht eindeutig über der Spekulation vom Typ „Sollte ich Python oder Ruby für mein nächstes Webprojekt verwenden“, die auf SO unerwünscht ist.

    – Benutzer4815162342

    16. Januar 2013 um 23:31 Uhr

  • @ user4815162342: Ich verstehe das und habe deshalb nicht dafür gestimmt, die Frage zu schließen; Das Thema (Titel) der Frage lautet jedoch “Was ist das Beste”, was einen Verstoß gegen die Richtlinien darstellt, und deshalb habe ich gefragt, ob es umformuliert werden könnte. 🙂 Es könnte zum Beispiel so einfach sein, “Was ist das Beste” durch “Gibt es eins” zu ersetzen.

    – Ken Weiß

    16. Januar 2013 um 23:35 Uhr


  • Normalerweise verwende ich libevent, wenn ich das möchte.

    – Singpolyma

    16. Januar 2013 um 23:42 Uhr

libMill ist wahrscheinlich das, wonach Sie suchen: http://libmill.org/

Es implementiert Threads auf Benutzerebene im Stil des Go-Lang-Kanals.

Und es wird von dem superschlauen Martin Sústrik, dem Schöpfer von ZeroMQ, entwickelt http://250bpm.com/. Also muss es gut sein ☺

Ich habe weder die Kommentare für den folgenden Code noch irgendwelche Beispiele mehr – dies ist eine portable (Pseudo-) Thread-Bibliothek, die als Präprozessor-Makros implementiert ist

     typedef struct
     {
     unsigned int magic;
     unsigned short ctx;
     unsigned char is_destroyed;
     }
     _run;

     typedef struct
     {
     unsigned int magic;
     unsigned int cnt;
     }
     _sem;


     #define aa_RUNNER_WAITING             0
     #define aa_RUNNER_YIELDED             1
     #define aa_RUNNER_EXITED              2
     #define aa_RUNNER_ENDED               3

     #define aaRunnerCreate(rp)            (rp)->magic="runr"; (rp)->ctx=0; (rp)->is_destroyed=NO
     #define aaRunnerDestroy(rp)           (rp)->is_destroyed=YES

     #define aaRunnerThread(args)          C args
     #define aaRunnerBegin(rp)             { C yflag=YES; if(yflag) {}  switch((rp)->ctx) { case 0:
     #define aaRunnerEnd(rp)               } yflag=NO; if(yflag) {}  aaRunnerCreate(rp); return aa_RUNNER_ENDED; }

     #define aaRunnerWaitUntil(rp,condx)   do  { (rp)->ctx=__LINE__; case __LINE__: if(!(condx))  { return aa_RUNNER_WAITING;  }  } while(0)
     #define aaRunnerWaitWhile(rp,condi)   aaRunnerWaitUntil((rp),!(condi))
     #define aaRunnerWaitThread(rp,thr)    aaRunnerWaitWhile((rp),aaRunnerSchedule(thr))
     #define aaRunnerWaitSpawn(rp,chl,thr) do { aaRunnerCreate((chl));  aaRunnerWaitThread((rp),(thr)); } while(0)

     #define aaRunnerRestart(rp)           do { aaRunnerCreate(rp); return aa_RUNNER_WAITING; } while(0)
     #define aaRunnerExit(rp)              do { aaRunnerCreate(rp); (rp)->magic=0; return aa_RUNNER_EXITED;  } while(0)

     #define aaRunnerSchedule(f)           ((f)<aa_RUNNER_EXITED)
     #define aaRunnerYield(rp)             do { yflag=NO; (rp)->ctx=__LINE__; case __LINE__: if(!yflag||!((rp)->is_destroyed))  { return aa_RUNNER_YIELDED;  }  } while(0)
     #define aaRunnerYieldUntil(rp,condi)  do { yflag=NO; (rp)->ctx=__LINE__; case __LINE__: if(!yflag||!(condi)) { return aa_RUNNER_YIELDED;   }   } while(0)

     #define aaRunnerSemInit(sp,c)         (sp)->magic="runs"; (sp)->cnt=c
     #define aaRunnerSemWait(rp,sp)        do { aaRunnerWaitUntil(rp,(sp)->cnt>0); --(sp)->cnt;  } while(0)
     #define aaRunnerSemSignal(rp,sp)      ++(sp)->cnt

  • Whow danke fürs Teilen!

    – Cetin Sert

    31. Januar 2013 um 5:11 Uhr

Benutzer-Avatar
R.. GitHub HÖREN SIE AUF, ICE ZU HELFEN

Verwenden Sie POSIX-Threads. Sie sind in jeder modernen Implementierung “grün”, nicht im Sinne von “Grünen Fäden”, sondern im Sinne von leicht und effizient. Es gibt keine portable Möglichkeit, Ihre eigenen Threads auf einfache C- oder POSIX-Minus-Threads zu rollen. Wie OP erwähnt, gibt es einige Bibliotheken, die grüne Threads/Co-Routinen auf nicht-portable Weise implementieren (oft trotz der Behauptung, Portabilität).

Der am nächsten tragbare Ansatz ist die Verwendung von makecontext/swapcontext, und leider kann dies nicht gut funktionieren, da Systemaufrufe ausgeführt werden müssen, um die Signalmaske bei jedem Wechsel zwischen “Threads” zu speichern / wiederherzustellen. Dies macht das Umschalten zwischen “grünen” Threads teurer als einen Kontextwechsel zwischen Kernel-Level-Threads in einer “echten” POSIX-Thread-Implementierung und negiert im Grunde jeden behaupteten Vorteil von “grünen Threads”.

Nicht-portable Ansätze, die sich nicht um die Signalmaske kümmern, könnten maschinenspezifisches asm verwenden, um die Kontextwechsel vollständig im Benutzerbereich durchzuführen, und theoretisch eine bessere Leistung erbringen als Threads auf Kernelebene, aber die Leistung würde sofort wieder aus dem Fenster fliegen Sie führen IO ein, da ein Thread, der IO ausführen soll, zuerst teure Tests durchführen müsste, um zu prüfen, ob die Operation blockiert, und wenn dies der Fall ist, die Kontrolle an einen anderen Thread zu übergeben.

Ich bleibe bei meiner Position, dass „grüne Fäden“ eine Idee sind, deren Zeit lange vorbei ist. Dies scheint auch die Position der Austin Group (verantwortlich für POSIX) zu sein, die die entfernt hat ucontext Funktionen in POSIX 2008 und empfohlener Ersatz durch POSIX-Threads (die jetzt ein obligatorisches Feature sind).

  • POSIX-Threads sind entschieden nicht grüne Fäden, wie dieser Begriff ist allgemein verstanden. Die Linux-Implementierung von POSIX-Threads erstellte immer Threads auf Betriebssystemebene in 1-zu-1-Korrespondenz mit POSIX-Threads, und Solaris, FreeBSD und NetBSD wechselten alle irgendwann in ihrer Geschichte zum 1-zu-1-Modell.

    – Benutzer4815162342

    16. Januar 2013 um 23:26 Uhr


  • … was Ihnen Haskell-Threads sagt kann auf Kerne verteilt werden, also aus den von Ihnen angenommenen Gründen nicht veraltet, @R.. , und sicherlich erheblich leichter als Betriebssystem-Threads.

    – AndreasC

    16. Januar 2013 um 23:58 Uhr

  • Auch wenn das Konzept des grünen Fadens obsolet ist (was umstritten ist), die Begriff wohldefiniert ist, und die Behauptung, dass “[POSIX threads] sind in jeder modernen Implementierung ‘grün'” ist falsch. Wie ich bereits geschrieben habe, sind alle modernen Implementierungen von POSIX-Threads 1-zu-1-Zuordnungen zu Betriebssystem-LWPs, was das genaue Gegenteil von grünen Threads ist.

    – Benutzer4815162342

    17. Januar 2013 um 2:56 Uhr

  • Kann ich 1M Posix-Threads auf einem vernünftigen Laptop starten?

    – Don Stewart

    17. Januar 2013 um 13:39 Uhr

  • @R.. hpaste.org/80868 erstellt 1M Threads. Mit einem 256-Byte-Thread-Stack weist er insgesamt 300 MB zu und ist in 2,7 Sekunden fertig. Ich würde Liebe um die äquivalente Skalierung mit Posix-Threads zu sehen.

    – Don Stewart

    17. Januar 2013 um 14:35 Uhr


1345310cookie-checkWelche Green-Threads-Bibliotheken sind für C verfügbar, die mit der Leistung und Benutzerfreundlichkeit der Green-Threads von Haskell mithalten können? [closed]

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

Privacy policy