2015-03-12 9 views
10

Sto cercando di incorporare un interprete Ruby1.9 in un programma. Attualmente sto usando forkOS nel mio pacchetto hruby, ma sembra che funzioni solo per Ruby 1.8 e 2.x. Sembra che 1.9 abbia bisogno di essere eseguito nella discussione principale. Come nodo laterale, c'è no documentazione come fare una cosa del genere, quindi l'unico puntatore al mio problema attuale è here.Come prendere il controllo del thread del sistema operativo principale in Haskell?

C'è un modo per assumere il controllo del thread principale per eseguire tutte le mie chiamate FFI?

+1

Forse un'opzione potrebbe utilizzare un hack simile a ['postGUISync'] (http://hackage.haskell.org/package/gtk3-0.13.4/docs/Graphics-UI-Gtk-General-General.html #v: postGUISync) del pacchetto 'gtk'. (Non sono sicuro se questo è veramente rilevante, ma ...) – chi

+1

Se ho capito bene, questo è come [la mia chiamata a makeSafe] (http://hackage.haskell.org/package/hruby-0.2.7/docs/ Esteri-rubino-Safe.html # v: makeSafe). Ciò è necessario perché l'interprete ruby ​​si aspetta che tutte le chiamate siano fatte dallo stesso thread, tuttavia è possibile che più thread abbiano accesso alle funzioni ruby. Comunque nel caso di GTK sembrano avere anche un binding per eseguire le cose nel ciclo principale (che non è necessariamente il thread principale) ... – bartavelle

+0

Penso che se avvii Haskell dal thread principale e poi chiami in Haskell tramite il (ffi) [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi-ghc.html#using-own-main] il thread Haskell viene quindi associato al thread principale e tutte le chiamate FFI da quel thread sembreranno provenire dal thread C principale. – Alex

risposta

1

Dopo aver eseguito alcuni test e aver letto la documentazione, sono giunto alle seguenti conclusioni. Il rapporto dice che tutto questo è definito dall'implementazione, quindi non esiste un modo standard. Il modulo Control.Concurrent indica nella documentazione che main è un thread associato, tuttavia non richiede che sia uguale al thread del sistema operativo principale.

Sperimentalmente (almeno su Linux 64-bit con GHC 7.8 e 7.10-rc3) il thread principale è il thread del sistema operativo. Dato che il thread principale è legato sembra che non ci sarebbe alcun motivo per questo essere diverso su altre piattaforme GHC, ma non posso testare altre piattaforme.

In termini di implementazione effettiva se si desidera programmare come se Ruby fosse in un thread diverso, è possibile eseguire la maggior parte delle cose non ruby ​​in un thread diverso e comunicare con il thread principale (che parla all'interprete ruby) tramite uno dei due MVar se TVar s. Vedi il commento di @chi per un esempio di come questo viene fatto in gtk.

In termini di un'interfaccia di libreria è possibile avere una funzione di inizializzazione che richiede una continuazione. La libreria dirotta il thread all'inizializzazione e quindi chiama la continuazione su un altro thread. Naturalmente è necessario documentare agli utenti che deve essere richiamato nel thread principale.

+0

Sembra che funzioni. Tranne che fallisce con il mio caso d'uso, poiché l'interprete ruby ​​non sembra funzionare bene con il runtime di Haskell :( – bartavelle

Problemi correlati