Haskell FFI : Foreignptr은 해방되지 않는 것 같습니다 (아마도 GHC 버그일까요?)

StackOverflow https://stackoverflow.com/questions/1022336

  •  06-07-2019
  •  | 
  •  

문제

다음 코드 스 니펫을 고려하십시오

import qualified Foreign.Concurrent
import Foreign.Ptr (nullPtr)

main :: IO ()
main = do
  putStrLn "start"
  a <- Foreign.Concurrent.newForeignPtr nullPtr $
    putStrLn "a was deleted"
  putStrLn "end"

다음 출력을 생성합니다.

start
end

나는 볼 것이라고 기대했을 것이다 "a was deleted"어딘가에 start..

무슨 일이 일어나고 있는지 모르겠습니다. 몇 가지 추측이 있습니다.

  • 프로그램이 완료되면 쓰레기 수집가가 나머지 물체를 수집하지 않습니다.
  • putStrLn 이후의 일을 중단합니다 main 마무리. (BTW 나는 외국 수입과 같은 것을 시도했다 puts 그리고 같은 결과를 얻었습니다)
  • 내 이해 ForeignPtr 부족합니다
  • GHC 버그? (ENV : GHC 6.10.3, Intel Mac)

사용할 때 Foreign.ForeignPtr.newForeignPtr 대신에 Foreign.Concurrent.newForeignPtr 작동하는 것 같습니다.

{-# LANGUAGE ForeignFunctionInterface #-}

import Foreign.C.String (CString, newCString)
import Foreign.ForeignPtr (newForeignPtr)
import Foreign.Ptr (FunPtr)

foreign import ccall "&puts" puts :: FunPtr (CString -> IO ())

main :: IO ()
main = do
  putStrLn "start"
  message <- newCString "a was \"deleted\""
  a <- newForeignPtr puts message
  putStrLn "end"

출력 :

start
end
a was "deleted"
도움이 되었습니까?

해결책

문서에서 forex.foreign.newforeignptr:

마지막 참조가 삭제 된 후 결승자가 얼마나 빨리 실행되는지에 대한 보장은 없습니다. 이것은 Haskell Storage Manager의 세부 사항에 따라 다릅니다. 실제로, 파이널 라이저가 전혀 실행된다는 보장은 없습니다. 프로그램은 최종화 업체로 종료 될 수 있습니다.

따라서 정의되지 않은 행동에 빠지게됩니다. 즉, 모든 일이 발생할 수 있으며 플랫폼에서 플랫폼으로 변경 될 수 있습니다 (Windows 아래에서 보았 듯이) 또는 릴리스 릴리스.

두 기능간에보고있는 행동 차이의 원인은 문서에 의해 암시 될 수 있습니다. 외국 .concurrent.newforeignptr:

이 최종화기는 반드시 별도의 스레드에서 실행됩니다 ...

외국의 외국 버전의 최종화기가 기본 스레드를 사용하지만 외국 스레드가 별도의 스레드를 사용하는 경우 다른 스레드가 작업을 완료하기를 기다리지 않고 기본 스레드가 종료 될 수 있습니다. 다른 스레드는 결승전을 실행하지 않습니다.

물론, 외국인의 문서는 주장하고,

유일한 보장은 프로그램이 종료되기 전에 최종화기가 실행된다는 것입니다.

파이널 제이저가 다른 스레드에서 실행 중이라면 작업을 수행하는 데 임의의 시간이 걸릴 수 있으므로 (영원히 차단), 따라서 메인 스레드는 절대 없기 때문에 실제로 이것을 주장해야할지 확신하지 못합니다. 프로그램이 종료되도록 강요 할 수 있습니다. 그것은 이것과 충돌 할 것입니다 Control.concurrent:

독립형 GHC 프로그램에서는 프로세스가 종료 되려면 주 스레드 만 종료해야합니다. 따라서 다른 모든 포크 스레드는 메인 스레드와 동시에 단순히 종료됩니다 (이러한 종류의 행동에 대한 용어는 "데모닉 스레드"입니다).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top