- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我已经编写了下面的代码,并注意到 killThread
阻塞并且线程仍在继续。只有当我在 forkProcess 中执行此操作时才会发生这种情况,如果我删除 forkProcess,一切都会按预期进行。
{-# LANGUAGE TupleSections #-}
module Main where
import Control.Concurrent
import Control.Monad
import System.Posix.Process
{-# NOINLINE primes #-}
primes :: [Integer]
primes = 2:[x | x <- [3..], all (not . flip isDivisorOf x) (takeWhile (< truncate (sqrt $ fromInteger x :: Double)) primes)]
where x `isDivisorOf` y = y `rem` x == 0
evaluator :: Show a => [a] -> IO ()
evaluator xs = do
putStrLn "[Evaluator] Started evaluator."
forM_ xs $ \x -> putStrLn $ "[Evaluator] Got result: " ++ show x
putStrLn "[Evaluator] Evaluator exited."
test :: IO ThreadId
test = forkIO (evaluator $ filter ((== 13) . flip rem (79 * 5 * 7 * 3 * 3 * 2 * 3)) primes) -- Just some computation that doesn't finsish too fast
main :: IO ()
main = do
pid <- forkProcess $ do
a <- test
threadDelay $ 4000 * 1000
putStrLn "Canceling ..."
killThread a
putStrLn "Canceled"
void $ getProcessStatus True False pid
$ ghc test.hs -O -fforce-recomp -threaded -eventlog -rtsopts # I also tried with -threaded
$ ./test +RTS -N2 # I also tried without -N
[Evaluator] Started evaluator.
[Evaluator] Got result: 13
[Evaluator] Got result: 149323
[Evaluator] Got result: 447943
[Evaluator] Got result: 597253
[Evaluator] Got result: 746563
[Evaluator] Got result: 1045183
Canceling ...
[Evaluator] Got result: 1194493
[Evaluator] Got result: 1642423
[Evaluator] Got result: 1791733
[Evaluator] Got result: 2090353
[Evaluator] Got result: 2687593
[Evaluator] Got result: 3135523
[Evaluator] Got result: 3284833
[Evaluator] Got result: 4777933
[Evaluator] Got result: 5375173
^C[Evaluator] Got result: 5524483
^C
这不是因为没有内存分配而导致 GHC 的线程调度程序无法运行的常见问题。我通过使用 +RTS -sstderr
运行程序验证了这一点,这表明垃圾收集器运行非常频繁。我在 linux 64bit 上运行这个。
最佳答案
这bug report注意到 forkProcess
屏蔽了子进程中的异步异常,尽管文档中没有这样的指示。该行为应在 7.8.1 发布时修复。
当然,如果屏蔽了异步异常,killThread
里面的throw
就会无限阻塞。如果您简单地删除 main
中包含 forkProcess
和 getProcessStatus
的行,程序将按预期运行:
module Main where
import Control.Concurrent
import Control.Monad
import System.Posix.Process
{-# NOINLINE primes #-}
primes :: [Integer]
primes = 2:[ x | x <- [3..], all (not . flip isDivisorOf x) (takeWhile (< truncate (sqrt $ fromInteger x :: Double)) primes)]
where x `isDivisorOf` y = y `rem` x == 0
evaluator :: Show a => [a] -> IO ()
evaluator = mapM_ $ \x ->
putStrLn $ "[Evaluator] Got result: " ++ show x
test :: IO ThreadId
test = forkIO (evaluator $ filter ((== 13) . flip rem (79 * 5 * 7 * 3 * 3 * 2 * 3)) primes) -- Just some computation that doesn't finsish too fast
main :: IO ()
main = do
a <- test
threadDelay $ 4000 * 1000
putStrLn "Canceling ..."
killThread a
putStrLn "Canceled"
我使用 ghc --make -threaded async.hs
构建它并使用 ./async +RTS -N4
运行。
如果出于某种原因您需要一个单独的进程,您将必须在 GHC 7.6.3 中手动取消屏蔽子进程中的异步异常。
关于linux - forkIO/killThread 与 forkProcess 的交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22052575/
我没有在haskell中做过任何网络化的事情,所以我现在尝试一下。我使用 Oleg 的 ZFS 作为模板如何做到这一点。 IIRC 他没有使用线程,而是使用“定界延续”,所以我想知道是否也可以在不使用
我正在尝试在 Haskell 中使用并发进行特定优化,其中只需要两个值中的一个,并且根据情况,创建其中一个值可能比另一个快得多。 我想我可以只用 forkIO 运行 2 个线程,然后等到一个值放入 M
我在做基准测试 forkIO使用以下代码: import System.Time.Extra import Control.Concurrent import Control.Monad import
我试图了解协程,但考虑到 forkIO 线程的存在,我不太了解它们的目的。哪些用例需要在线程上使用协程? 最佳答案 如果您在谈论特定的 Haskell 协程实现(如果是,请添加链接),或者关于一般概念
如果我使用 forkIO 创建一个线程,我需要提供一个函数来运行并取回一个标识符(threadID)。然后我可以通过例如与这种动物交流。工作负载,MVAR 等。但是,据我了解,创建的线程非常有限,只能
我们如何让用户传递一个 eventHandler,它使用 stateMonad 但在单独的线程中调用?比如下面的例子中,应该如何调用forkIO,以便eventHandler可以调用操作呢?我是 Ha
我正在尝试让多个客户端连接到服务器。我设法做的是通过使用服务器将一个客户端连接到服务器: main = withSocketsDo $ do socket
我正在使用 Haskell 轻量级线程 ( forkIO ) 使用以下代码: import Control.Concurrent beginTest :: IO () beginTest = go
我希望有人能帮助我理解为什么下面的代码会生成下面的输出。代码来自 Simon Marlow 书中的并发章节(链接如下)。 根据对各种功能的描述,我假设第二个 putMVar鉴于 (i) 两个 putM
我不确定 Haskell 中的 forkIO/forkOS 和 forkProcess 之间有什么区别。据我了解,forkIO/forkOS 更像是线程(类似于 C 中的 pthread_create
我已经编写了下面的代码,并注意到 killThread 阻塞并且线程仍在继续。只有当我在 forkProcess 中执行此操作时才会发生这种情况,如果我删除 forkProcess,一切都会按预期进行
我正在寻找的是一个简单的类型函数: alive :: ThreadID -> IO Bool 最佳答案 这对于标准 base 是不可能的。据我所知,库,但您可以使用 GHC 特定的 API 来获取线程
我是一名优秀的程序员,十分优秀!