问题描述
我正在编写一个CLI程序,当我执行program | head
之类的二进制文件时,我得到:
Error: unhandled exception: errno: 32 `broken pipe` [IOError]
import posix
signal(SIG_PIPE,SIG_IGN)
在我的主要过程中,但这并没有使错误消失。该程序使用threadspool
,调用另一个过程来分析输入行池。 (我不知道这是否与问题有关)
更新:
- 这是我无法使用的程序:https://pastebin.com/aQaRgfXR(以
responses.add(spawn parseArray(readspool,mergeOptions))
产生的线程) - 这是完整的错误:
/Users/telatina/miniconda3/nim/lib/pure/concurrency/threadpool.nim(377) slave
/Users/telatina/git/nim-stuff/orf/src/porfidus.nim(307) parseArrayWrapper
/Users/telatina/git/nim-stuff/orf/src/porfidus.nim(247) parseArray
/Users/telatina/miniconda3/nim/lib/system/io.nim(155) checkErr
/Users/telatina/miniconda3/nim/lib/system/io.nim(138) raiseEIO
Error: unhandled exception: errno: 0 `Undefined error: 0` [IOError]
解决方法
基于@ julian-fondren的答案和您的代码,我能够复制您的错误。
import os,posix,threadpool
signal(SIG_PIPE,SIG_IGN)
proc noise =
for i in 0 ..< int(1e6):
stdout.write($i & '\n')
threadpool.spawn noise()
threadpool.spawn noise()
threadpool.sync()
针对后续人员。
您也在代码中使用may throw an IO Exception的代码中stdout.write
由于您使用SIG_IGN
,因此线程在收到SIG_PIPE
时不会停止运行,而是继续在断开的管道上调用stdout.write
,从而引发异常。
要解决此问题,我发现了三个选项
-
处理异常
对于您的代码因“错误:未处理的异常”而惊慌的情况,这是最通用的解决方案
to handle an exception in Nim使用
try
和except
。
stdout.write($i & '\n')
变为
try:
stdout.write($i & '\n')
except IOError:
#handle it by ending the program
quit()
#or ignore it with
#discard
- 处理信号
在我的机器上,使用
SIG_DFL
会导致线程无提示地终止,从而按您的方式运行,但这取决于平台。因此,您还可以注册自己的信号处理程序(对丑陋的演员表示抱歉)
#signal(SIG_PIPE,SIG_DFL)
signal(SIG_PIPE,cast[typeof(SIG_IGN)](proc(signal:cint) =
stderr.write("handled sigpipe\n")
quit()
))
- 只需使用echo
echo
与stdout.write
不同,它不会引发异常,因此对于这种情况,它可能是最简单的解决方法
使用nim 1.2.6和以下程序(不要以其为好样式):
import os,SIG_IGN)
proc noise =
for i in 0 ..< int(1e6):
echo i
threadpool.spawn noise()
threadpool.spawn noise()
threadpool.sync()
当按以下方式运行时,它显然会忽略EPIPE,并明显地从多个线程进行打印(因为看到了两个60,然后当两个线程到达循环结束时都会有延迟):
$ ./brokenpipe |grep -m2 -F 60
60
60
注释掉signal
调用后,最后一条命令将引发错误:
$ ./brokenpipe |grep -m2 -F 60
60
60
Traceback (most recent call last)
/home/jfondren/.choosenim/toolchains/nim-1.2.6/lib/pure/concurrency/threadpool.nim(377) slave
/home/jfondren/nim/learn/brokenpipe.nim(8) noiseWrapper
/home/jfondren/nim/learn/brokenpipe.nim(6) noise
/home/jfondren/.choosenim/toolchains/nim-1.2.6/lib/system/io.nim(648) echoBinSafe
SIGPIPE: Pipe closed.
因此您的解决方案似乎可以正常工作,并且您真的需要一个无法解决的最小问题示例。