2012-12-28 29 views
5

我正在寫一個Haskell結合一些圖書館,有一個函數void foo(),這裏面調用select()代碼接口。當我從Haskell調用這個函數時,select()調用開始不斷返回EINTR。這混淆了庫代碼,並開始循環。與調用select()

#haskell IRC頻道,有人告訴我,從綁定線程運行foo()。我用runInBoundThread這個,現在一切似乎工作。但在少數情況下,我在控制檯收到Alarm clock消息(好吧,我發現它意味着應用程序捕獲SIGALRM)。

我不知道這是來處理這個問題正確的方法,我不希望依賴於Control.Concurrency。我該怎麼辦?

+0

'Control.Concurrent'是標準庫的一部分 - 這取決於它是一樣的視哈斯克爾。你爲什麼不想使用該模塊? (雖然我承認報警消息是奇怪的,我從來沒有看到) – luqui

+6

我聽到GHC使用SIGALRM和SIGVTALRM內部線程管理。如果外部代碼線程對這些信號敏感,則應該阻止它們進入該線程。見例如'Database.HDBC.MySQL.RTS'中的'withRTSSignalsBlocked'。 –

回答

2

原因SIGALRM是GHC的運行時使用舊的代碼路徑管理定時器的東西。這個舊的代碼路徑開啓了,因爲GHC的配置腳本在檢查create_timer()函數時有一些linuxism。修復它使得GHC使用與所有平臺上使用的機制相同的機制,並消除了有問題的錯誤。

相關Phabricator DIFF:https://phabricator.haskell.org/D831

1

N.M.的評論是正確的:在withRTSSignalsBlocked代碼將從您ffi'd代碼隱藏的信號:http://hackage.haskell.org/packages/archive/HDBC-mysql/0.6.6.1/doc/html/Database-HDBC-MySQL.html#v:withRTSSignalsBlocked

這也應該可以消除runInBoundThread的需要,我想。

+0

'withRTSSignalsBlocked act = runInBoundThread。 alloca $ \ set - > do ...'嗯...好吧,我會盡力而爲。 – arrowd

+0

這並沒有幫助我。如果我在'finally'的rhs上移除'runInBoundThread'和'pthread_sigmask'調用,它就會起作用。但是,如果我理解正確,這是完全錯誤的。 – arrowd

+0

然後,很明顯,你調用由withRTSSignalsBlocked把守的動作不是這是造成錯誤的一個,或者以某種方式做懶IO的東西。即阻斷信號的作用,但它們在執行該動作時在其他地方被捕獲。 – sclv