Implementierung von MVar in C?

9

Gibt es eine bekannte Implementierung von Haskell MVar in C? Es gibt ein Beispiel zur Implementierung in C ++. Aber ich möchte es in C implementieren - sagen wir nur MVar CInt Äquivalent in C für jetzt. Das Schreiben von Synchronisationsprimitiven kann schwierig sein. Daher möchte ich Doppelarbeit vermeiden, wenn jemand es bereits getan hat. Ich habe das obige C ++ - Beispiel nicht gut genug verstanden, um es souverän in C zu übersetzen - es versteckt die algorithmischen Details sehr gut aus meinem C ++ - unerfahrenen Verstand:)

Der Grund, warum ich über das Schreiben von MVar in C nachdenke, ist, dass es mir die Verwendung der FFI-Bindung an eine externe C-Bibliothek sehr erleichtert, um den Datenstrom zu erhalten und Haskell-Threads zum Abrufen der Daten zu verwenden Vektoren, um das Marshalling der Daten zu vermeiden - MVar CInt speichert hier, wie viel von den speicherbaren Vektoren gefüllt wurde. Ich muss sicherstellen, dass C-Threads, die an Speicherorte schreiben, blockiert werden, während ein Haskell-Thread die Daten liest. Hier hilft die MVar-Synchronisation auf der C-Seite. Es ist auch viel schneller, unsichere oder sogar sichere C-Funktion von Haskell (~ 15ns für unsichere, ~ 150ns für sichere in meinem Test) zu nennen, als Callback in Haskell von C (~ 5us). Wenn Callbacks schnell wären, hätte ich stattdessen einen C-Funktion-Call zurück in Haskell und blockiere Haskell MVar.

Aktualisierung:

Algorithmus in Pseudo-Code wird ebenso gut. Es sollte ziemlich einfach sein, es in C zu implementieren, mit dem Algorithmus für newEmptyMVar, takeMVar und putMVar.

    
Sal 18.01.2012, 04:07
quelle

2 Antworten

3

MVar kann in C mit einer Struktur wie folgt implementiert werden:

%Vor%

put_cond wird von Threads verwendet, die Werte in MVar eingeben, um anderen Threads zu signalisieren, die darauf warten, den Wert von MVar zu erhalten. take_cond ist das analoge Gegenstück zu Take. Wie für die Planung ist es Standardplanung.

value ist ein void-Zeiger - also kann die obige Struktur verwendet werden, um jeden Wert in einem MVar zu schützen - natürlich lässt C Sie diesen Zeiger außerhalb von MVar schreiben - also ist das Programm dafür verantwortlich Stellen Sie sicher, dass dies nicht geschieht (indem Sie verhindern, dass value Zeiger außerhalb von MVar weggespritzt wird - greifen Sie immer über MVar-Funktionen darauf zu).

Initialisierung von MVar :

%Vor%

Empty MVar - verwendet obige Funktion:

%Vor%

putMVar :

%Vor%

takeMVar :

%Vor%

Der vollständige Code ist github , mit Beispiel , das zeigt, wie MVar verwendet wird.

MVar ist ziemlich schnell, wenn nur ein Thread darauf zugreift (und starke Konkurrenz). Aber unter starken Konflikten und mehreren Threads (sogar zwei), skaliert es sehr schlecht. Das ist keine Überraschung, weil Pthreads funktionieren. Ich habe MVar in Haskell als sehr gut mit mehreren Threads gefunden. Dies ist keine Überraschung, wenn man bedenkt, wie gut Lightweight-Threads und Parallelitäts-Primitive in GHC implementiert sind.

    
Sal 20.01.2012, 13:13
quelle
0

Der Code im Beispiel ist nicht sehr C ++ - spezifisch. Die wesentlichen Bits sind genau die pthread -Fragmente.

    
ShiDoiSi 18.01.2012 09:15
quelle

Tags und Links