为了练习并发编程,我写了下面这个(不太优化的)程序,它会反复计算输入值之后第一个素数的值:
我希望在后台有一个工作线程来执行实际的计算,并在完成后立即输出
import Control.Concurrent
import Control.Concurrent.Chan
import Control.Monad (forever)
primeAtLeast n = -- Some pure code that looks up the first prime at least as big as n
outputPrimeAtLeast n = putStrLn $ show $ (n, primeAtLeast n)
main = do
chan <- newChan
worker <- forkIO $ forever $ readChan chan >>= outputPrimeAtLeast
forever $ (readLn :: (IO Int)) >>= (writeChan chan)
killThread worker
我希望在后台有一个工作线程来执行实际的计算,并在完成后立即输出
(n, 最小素数n)
。目前的情况是:一旦我输入数字 n
,它会立即输出 (n,
并将控制权返回给主线程,在后台计算 primeAtLeast n
,并在完成后输出第二部分 最小素数n)
。所以,putStrLn
不是原子性的吗?还是问题出在哪里?
show
和putStrLn
的这种行为 ;) - Random DevputStrLn
可以处理无限长的字符串,或者在你输出部分初始内容后引发异常的字符串,例如show (1, undefined)
。如果它是原子的,就不能处理这种情况。 - Ørjan Johansen