我正在 SELECT c.name
, s.date
, s.score
FROM country c
LEFT
JOIN score s
ON s.country_id = c.id
LEFT
JOIN ( SELECT o.country_id
, o.date
, MAX(o.score) AS max_date_score
FROM ( SELECT m.country_id
, MAX(m.date) AS max_date
FROM score m
GROUP
BY m.country_id
) n
JOIN score o
ON o.country_id = n.country_id
AND o.date = n.max_date
GROUP
BY o.country_id
, o.date
) p
ON p.country_id = c.id
ORDER
BY p.date DESC
, p.max_date_score DESC
, c.name ASC
, s.date ASC
, s.score DESC
中测试一些分叉线程的函数,有点像这样:
ghci
结果是:
myForkingFunction = do
tid <- forkIO (workerFunction)
putStrLn ("Worker thread: " ++ show tid)
putStrLn ("...lots of other actions...")
where workerFunction = do
putStrLn "In real life I'm listening for jobs...."
workerFunction
(依此类推)
然后,当我 > myForkingFunction
Worker thread: ThreadId 216
...lots of other actions...
> In real life I'm listening for jobs....
In real life I'm listening for jobs....
In real life I'm listening for jobs....
In real life I'm listening for jobs....
遍历代码时,我注意到即使重新加载,我的:r
仍在运行。
因此,我认为可以只看打印输出并执行workerFunction
或其他任何操作。
但是首先,我需要从killThread (ThreadId 234)
导入ThreadId(..)
吗?
然后我得到这个错误:
GHC.Conc.Sync
所以我认为我一定要解决这个错误?
答案 0 :(得分:4)
我认为没有任何方法可以构建ThreadId
(例如,根据show
的结果)。请参见this question,因此您需要保留ThreadId
返回的forkIO
,例如通过将功能更改为:
myForkingFunction = do
tid <- forkIO (workerFunction)
putStrLn ("Worker thread: " ++ show tid)
putStrLn ("...lots of other actions...")
return tid
并在ghci中做
> tid <- myForkingFunction
> killThread tid
您得到的错误有点令人困惑,我认为这与数字文字(例如216
)是多态的有关; ThreadId
的参数是ThreadId#
,它是未提升的类型,因此您可以在编译器甚至抱怨“没有实例Num ThreadId#”之前看到错误,
答案 1 :(得分:4)
ThreadId
值由运行时特别处理。您不能只创建一个。创建线程时,您需要访问ThreadId
或由线程内部的forkIO
生成的myThreadId
。
只是为了获得额外的乐趣,当线程中的任何ThreadId
仍然可以访问时,线程不会被垃圾收集。因此,如果需要它们,您不能仅仅坚持使用它们。您实际上需要制定一个计划来管理线程。
我认为最好使用async library,它是各种链接操作,以确保当杀死父线程时,它也杀死所有子线程。这有点(或很多)笨拙的代码样式,但这是获得正确行为的最佳方法。
答案 2 :(得分:3)
ThreadId
实际上不是数字,尽管它具有与之相关的数字以供识别。 ThreadId
是ThreadId#
的包装,它是指向线程状态对象(TSO或RTS代码为StgTSO
)的指针。该对象包含有关线程的所有实际内部信息。无法将Int
转换为ThreadId
(我很确定运行时系统甚至不维护从线程ID号到ThreadId#
的映射,并且肯定有没有primop支持这种转换),因此您现在就可以放弃。 killThread
或throwTo
线程的唯一方法是坚持使用ThreadId
给您的forkIO
。请注意,杀死线程通常不是您想要停止它的方法。通常,您想通过通过MVar
与之通信来进行更多控制。大多数人使用async
库中的工具来管理并发。
答案 3 :(得分:-5)
问题在于killThread的参数是错误的。您需要写killThread 234
而不是killThread (ThreadId 234)
。你尝试过吗?