2012-03-31 8 views
1

내 프로그램이 네트워크 소켓에서 한 줄을 읽고이를 디스크에 씁니다. 라인이 길고 문자열이 끔찍한 성능을 가지기 때문에 나는 느린 바이트 문자열을 사용하기 시작했다.지연된 IO에 대한 강제 평가

  • 열려있는 파일을 hPut
  • 가까운 파일을 파일에
  • 쓰기 바이트 문자열을 쓰기 위해 : 지금은 하스켈 실제로 디스크에 전체 바이트 문자열을 세척, 그렇게하지 않고 디스크 파일 핸들에 hClose지나 갈 것으로 보인다

를 읽기위한

  • 열린 파일은 일반적으로 openFile: resource busy (file is locked) 발생합니다.

    평가를 시행하고 파일을 닫기 전에 전체 바이트 문자열이 기록 될 때까지 기다릴 수 있습니까? 그렇다면 파일이 실제로 해당 작업 후에 닫혔다는 것을 확신 할 수 있습니까?

  • +0

    당신은 ['hFlush'] (http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-IO.html#v:hFlush) 봤어? – huon

    +0

    플러시는'hClose'와 마찬가지로 도움이되지 않습니다. GHC는 기다리지 않고 통과합니다. –

    답변

    0

    유일한 답변은 "다른 용도로 사용"의 다양한 답변이므로 나만의 솔루션을 게시하고 있습니다. hClose 뒤에이 함수를 사용하면 지연 쓰기가 완료 될 때까지 스레드가 중지됩니다.

    waitForLazyIO location = do 
        t <- liftIO $ try $ openFile location AppendMode 
        handle t 
        where 
         handle (Right v) = hClose v 
         handle (Left e) 
          -- Add some sleep if you expect the write operation to be slow. 
          | isAlreadyInUseError e = waitForLazyIO location 
          | otherwise = throwError $ show e 
    
    +0

    이것은 제대로 작동 할 수도 있지만 솔직히 말해서 해킹이며, 실제로는 haskell 소프트웨어의 일반적인 표준이 아닙니다. 게으른 IO 경로는 개념이 조용하게 깨져 있기 때문에 함정으로 가득 차 있습니다. 현재 constant-memory IO 조작을위한 유일하게 실행 가능한 옵션은 [conduit] (http://hackage.haskell.org/package/conduit)이 인기있는 멤버 인 좌절 열거 자 (left-fold enumerator)의 패밀리입니다. –

    0

    지연된 I/O 및 지연 바이트 문자열 대신 엄격한 바이트 문자열을 사용하여 엄격한 I/O를 사용해보십시오.

    너무 비효율적 인 것으로 판명 된 경우 conduit 또는 유사한 패키지를 사용해보십시오.