Почему конец строки putStrLn находится вне блокировки потока? - PullRequest
5 голосов
/ 06 июля 2011

Когда я использую putStrLn txt из нескольких потоков в Haskell, возможно получить текст, интеркалированный концом строк, но если я использую putStr $ txt ++ "\n", всегда работает.

это правильно? Что я делаю не так?

Пример 1:

thread 1: putStrLn "txt 1"
thread 2: putStrLn "txt 2"
thread 3: putStrLn "txt 3"
thread 4: putStrLn "txt 4"
thread 5: putStrLn "txt 5"

Пример вывода:

txt 1txt 3
txt 2txt 5txt 4

Пример 2:

thread 1: putStr $ "txt 1" ++ "\n"
thread 2: putStr $ "txt 2" ++ "\n"
thread 3: putStr $ "txt 3" ++ "\n"
thread 4: putStr $ "txt 4" ++ "\n"
thread 5: putStr $ "txt 5" ++ "\n"

Всегда выводить одну строку для потока:

txt 1
txt 3
txt 2
txt 5
txt 4

Спасибо

Обновление: Я использую ghc 6.12.3 и base-4.2.0.2

Ответы [ 2 ]

7 голосов
/ 06 июля 2011

Насколько я могу судить, Haskell не предоставляет никаких гарантий безопасности потоков для putStr, putStrLn и друзей, поэтому было бы также разрешено чередовать посимвольные символы, даже при выполнении конкатенации вверхfront, как вы.

См. Могу ли я убедиться, что Haskell выполняет атомарный ввод-вывод? для примера того, как правильно синхронизировать ваш ввод-вывод.

3 голосов
/ 06 июля 2011

С определением из базы 4.3.0.0 (putStrLn s = do putStr s; putChar '\n' - спасибо, хаммар) я бы предположил, что putStr блокирует дескриптор stdout и, следовательно, может выводить строку без вставки.Это объясняет, почему вывод интеркалирует при использовании putStrLn: блокировка снимается после putStr, а другой поток получает блокировку до putChar.Однако я только размышляю.

В любом случае, обновление GHC, а вместе с ним и базовой библиотеки до 4.3.1.0 должно решить проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...