- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Haskell 轻量级线程 ( forkIO
) 使用以下代码:
import Control.Concurrent
beginTest :: IO ()
beginTest = go
where
go = do
putStrLn "Very interesting string"
go
return ()
main = do
threadID1 <- forkIO $ beginTest
threadID2 <- forkIO $ beginTest
threadID3 <- forkIO $ beginTest
threadID4 <- forkIO $ beginTest
threadID5 <- forkIO $ beginTest
let tID1 = show threadID1
let tID2 = show threadID2
let tID3 = show threadID3
let tID4 = show threadID4
let tID5 = show threadID5
putStrLn "Main Thread"
putStrLn $ tID1 ++ ", " ++ tID2 ++ ", " ++ tID3 ++ ", " ++ tID4 ++ ", " ++ tID5
getLine
putStrLn "Done"
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Main Thread
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very interesting string
Very VVVViMeeeenarrrrtiyyyyen r iiiieTnnnnshtttttreeeeierrrrnaeeeegdssss
ttttsiiiitTnnnnrhggggir nessssgatttt
drrrrIiiiiVdnnnne ggggr5
y1 ,VVVVi eeeenTrrrrthyyyyer reiiiieannnnsdtttttIeeeeidrrrrn eeeeg5ssss 2tttts,iiiit nnnnrTggggih nrssssgetttt
arrrrdiiiiVInnnnedggggr
y5 3VVVVi,eeeen rrrrtTyyyyeh rriiiieennnnsatttttdeeeeiIrrrrndeeeeg ssss 5tttts4iiiit,nnnnr ggggiT nhssssgrtttt
errrraiiiiVdnnnneIggggrd
y 5VVVVi5eeeen
rrrrtyyyye riiiiennnnsttttteeeeirrrrneeeegssss ttttsiiiitnnnnrggggi nssssgtttt
rrrriiiiVnnnneggggr
y VVVVieeeenrrrrtyyyye riiiiennnnsttttteeeeirrrrneeeegssss ttttsiiiitnnnnrggggi nssssgtttt
rrrriiiiVnnnneggggr
Very interesting string
s 最终彼此重叠,因为不知何故线程使用
putStrLn
同时最终在彼此之上写入标准输出。为什么会这样,以及如何(不求助于消息传递、计时或其他一些过于复杂和令人费解的解决方案)可以克服它?
最佳答案
简单地说,putStrLn
不是原子操作。每个字符都可以与来自不同线程的任何其他字符交错。
(我也不确定在多字节编码(如 UTF8)中是否保证多字节字符是原子处理的。)
如果你想要原子性,你可以使用共享互斥锁,例如
do lock <- newMVar ()
let atomicPutStrLn str = takeMVar lock >> putStrLn str >> putMVar lock ()
forkIO $ forever (atomicPutStrLn "hello")
forkIO $ forever (atomicPutStrLn "world")
do lock <- newMVar ()
let atomicPutStrLn str = withMVar lock (\_ -> putStrLn str)
forkIO $ forever (atomicPutStrLn "hello")
forkIO $ forever (atomicPutStrLn "world")
关于multithreading - Haskell forkIO 线程使用 putStrLn 在彼此之上写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32040536/
我知道如果我有多个线程调用 putStrLn没有任何类型的并发控制,线程的输出可能是交错的。 我的问题是 putStrLn这个交错输出是线程安全的模数吗? 我假设 putStrLn是一个缓冲的写操作,
我正在尝试 wxHaskell。我无法在 ghci 下运行该应用程序,因此我必须使用应用程序来测试它。我想用 println 调试来测试程序。但是,putStrLn 似乎在 GUI 中不起作用: {-
这个问题在这里已经有了答案: Why shouldn't I mix tabs and spaces? (1 个回答) 5年前关闭。 当我尝试编译下面的列表时 import System.Enviro
我正在尝试在 Haskell 函数中调用“打印输出”函数。 (一个简单的调试消息)。 以下是来自编译器(GHC 6.10)的代码和错误消息。 我不太明白为什么它把 putStr 混为一谈。调用和空数组
当我使用 putStrLn txt从 Haskell 的几个线程中,可以将文本插入行尾,但如果我使用 putStr $ txt ++ "\n"总是有效。 这样对吗?我做错了什么? 示例 1: thre
我制作了一个小型生命游戏程序,它可以自行迭代几代人。问题是每次迭代时,putStrLn 函数都会大大减慢,我不知道为什么。这是代码: import Control.Concurrent data Ce
我有一个字符串列表,并尝试了这个: ls = [ "banana", "mango", "orange" ] main = do map PutStrLn list_of_strings
为了练习并发编程,我编写了以下(次优)程序,该程序重复计算第一个大于用户输入的素数: import Control.Concurrent import Control.Concurrent.Chan
我刚刚编写了我的第一个 Haskell 程序,但是有一个我无法理解的错误。我认为这是正确的,因为我只是像书中的示例一样编写它。有人可以帮我吗? main = do putStrLn "Hell
这个问题在这里已经有了答案: Wrong IO actions order using putStr and getLine (1 个回答) 关闭去年。 我是从 Learn You a Haskel
下面的代码: Prelude> :t putStrLn putStrLn :: String -> IO () Prelude> putStrLn "test" test it :: () Prelu
最近,我开始学习 Haskell,因为我想扩大我在函数式编程方面的知识,我必须说到目前为止我真的很喜欢它。我目前使用的资源是 Pluralsight 上的类(class)“Haskell Fundam
这个问题已经有答案了: IO happens out of order when using getLine and putStr (3 个回答) 已关闭 9 年前。 假设我们有一个简短的 haske
Prelude> mapM putStrLn ["a", "b"] a b [(),()] Prelude> mapM_ putStrLn ["a", "b"] a b 为什么第一个版本显示第三行而第
我试图通过添加对“putStrLn”的调用来显示一个 Haskell 函数: isPrime2 1 = False isPrime2 n = do putStrLn n null (f
我是 Haskell 的新手。我的 Haskell 脚本与 GHCi, Prelude> let a = putStrLn getLine 犯了这样的错误。 :1:17: Couldn't m
我正在使用 Haskell 轻量级线程 ( forkIO ) 使用以下代码: import Control.Concurrent beginTest :: IO () beginTest = go
实际上,标题说明了一切。我不明白为什么下面的代码实际上并没有打印“Hello World”而不是 >>=做。 main = fmap putStrLn getLine 目前,这是我的推理路线,请检查它
我有一个简单的程序,只需从用户处获取一个字符串和一个 key ,并使用凯撒密码函数对该字符串进行加密。该函数本身可以工作,所以我不会展示其来源。问题是,当编译器编译程序时,它将允许我输入所有 getL
我将 Haskell 与使用箭头语言扩展的 Yampa FRP 库一起使用。 我怎样才能在 SF 中做一个简单的 putStrLn? mySF = proc x -> do y IO ()
我是一名优秀的程序员,十分优秀!