ब्लॉक उद्धरण में भाग को अनदेखा करें, और नीचे अपडेट देखें - मैं इसके साथ जुड़े टिप्पणियों के कारण मूल गैर-समाधान को संरक्षित कर रहा हूं।
आप unsafe
रूप import
निशान के बाद से आप मुख्य धागा, जबकि समारोह निष्पादित हो रहा है ( @carl से नीचे टिप्पणी देखें) ब्लॉक करना चाहते हैं चाहिए। डिफ़ॉल्ट रूप से, आयात safe है, unsafe
नहीं।
foreign import ccall unsafe "wiring.h delay" c_delay :: CUInt -> IO()
इसके अलावा, अगर आप मल्टी-थ्रेडेड कोड लिखने की योजना है, GHC docs for multi-threaded FFI> बहुत उपयोगी: तो, समारोह हस्ताक्षर बदलते इस को मुख्य थ्रेड ब्लॉक बनाना चाहिए। This भी एक अच्छा स्टार्टर लगता है।
अद्यतन
व्यवहार (अगर मैं सही ढंग से याद करते हैं, इस GHC में जोड़ा गया 7.4+ कुछ कीड़े को ठीक करने) का संकेत करने के व्यवधान से निपटने की वजह से हो रहा है। यहां अधिक जानकारी: http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Signals
कृपया उपरोक्त पृष्ठ पर टिप्पणी दें: Signal handling differs between the threaded version of the runtime and the non-threaded version
।
दृष्टिकोण 1 - एफएफआई कोड में संभाल संकेत संभाल: एक खिलौना कोड नीचे है जो नींद में बाधा को नियंत्रित करता है। मैंने इसे गीक 7.6.1 के साथ लिनक्स 2.6.18 पर परीक्षण किया।
सी कोड:
/** ctest.c **/
#include <unistd.h>
#include <stdio.h>
#include <time.h>
unsigned delay(unsigned sec)
{
struct timespec req={0};
req.tv_sec = sec;
req.tv_nsec = 0;
while (nanosleep(&req, &req) == -1) {
printf("Got interrupt, continuing\n");
continue;
}
return 1;
}
हास्केल कोड:
{-# LANGUAGE ForeignFunctionInterface #-}
-- Filename Test.hs
module Main (main) where
import Foreign.C.Types
foreign import ccall safe "delay" delay :: CUInt -> IO CUInt
main = do
putStrLn "Sleeping"
n <- delay 2000
putStrLn $ "Got return code from sleep: " ++ show n
अब, GHC 7.6 के साथ संकलन के बाद।1 (आदेश: ghc Test.hs ctest.c
), यह नींद खत्म होने तक इंतजार कर रहा है, और संदेश हर बार नींद के समय व्यवधान संकेत हो जाता है प्रिंट:
./Test
Sleeping
Got interrupt, continuing
Got interrupt, continuing
Got interrupt, continuing
Got interrupt, continuing
....
....
Got return code from sleep: 1
दृष्टिकोण 2 - अक्षम SIGVTALRM FFI कोड कॉल करने से पहले, और पुन: सक्षम :
मुझे यकीन नहीं है कि SIGVTALRM को अक्षम करने के लिए क्या प्रभाव हैं। यह वैकल्पिक दृष्टिकोण है जो एफएफआई कॉल के दौरान एसआईजीवीटीएएलआरएम को अक्षम करता है, अगर आप एफएफआई कोड को बदल नहीं सकते हैं। इसलिए, नींद के दौरान एफएफआई कोड बाधित नहीं होता है (माना जाता है कि यह सिग्वाल्ट्रम है जो बाधा उत्पन्न कर रहा है)।
{-# LANGUAGE ForeignFunctionInterface #-}
-- Test.hs
module Main (main) where
import Foreign.C.Types
import System.Posix.Signals
foreign import ccall safe "delay" delay :: CUInt -> IO CUInt
main = do
putStrLn "Sleeping"
-- Block SIGVTALRM temporarily to avoid interrupts while sleeping
blockSignals $ addSignal sigVTALRM emptySignalSet
n <- delay 2
putStrLn $ "Got return code from sleep: " ++ show n
-- Unblock SIGVTALRM
unblockSignals $ addSignal sigVTALRM emptySignalSet
return()
मैं क्या कारण है पता नहीं है, लेकिन (का उपयोग करते हुए 'usleep', के बाद से मैं कोई wiringPi है) GHC के लिए गैर पिरोया आरटीएस के साथ, <= 7.2। *, यह इंतजार कर रहा है जब तक नींद है ऊपर। थ्रेडेड आरटीएस के साथ, या जीएचसी> = 7.4 के साथ, यह तुरंत निकलता है। शायद एक बग, लेकिन मुझे नहीं पता कि पुराने जीएचसी या नए में से कोई एक है या नहीं। –
वायरिंगपी के हेडर वायरिंग नहीं है Pi.h? –
@ डैनियल फिशर: क्या इसे नए जीएचसी/थ्रेडेड आरटीएस में एक बग नहीं होना चाहिए? क्या यह व्यवहार इस बात का तात्पर्य नहीं है कि एक कार्यक्रम में अंतिम कार्रवाई के रूप में सुरक्षित रूप से एक समारोह को कॉल करना असंभव है, क्योंकि इस बात की कोई गारंटी नहीं होगी कि यह समाप्त हो गया है? –