微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Nim中忽略“断管”异常

如何解决如何在Nim中忽略“断管”异常

我正在编写一个CLI程序,当我执行program | head之类的二进制文件时,我得到:

Error: unhandled exception: errno: 32 `broken pipe` [IOError]

我想让这个例外保持沉,然后尝试添加

import posix
signal(SIG_PIPE,SIG_IGN)

在我的主要过程中,但这并没有使错误消失。该程序使用threadspool调用一个过程来分析输入行池。 (我不知道这是否与问题有关)

更新:

/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,从而引发异常。

要解决此问题,我发现了三个选项

  1. 处理异常

    对于您的代码因“错误:未处理的异常”而惊慌的情况,这是最通用的解决方案

    to handle an exception in Nim使用tryexcept

stdout.write($i & '\n')变为

try:
  stdout.write($i & '\n')
except IOError:
  #handle it by ending the program
  quit()
  #or ignore it with
  #discard
  1. 处理信号 在我的机器上,使用SIG_DFL会导致线程无提示地终止,从而按您的方式运行,但这取决于平台。因此,您还可以注册自己的信号处理程序(对丑陋的演员表示抱歉)
#signal(SIG_PIPE,SIG_DFL)
signal(SIG_PIPE,cast[typeof(SIG_IGN)](proc(signal:cint) =
    stderr.write("handled sigpipe\n")
    quit()
  ))
  1. 只需使用echo echostdout.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.

因此您的解决方案似乎可以正常工作,并且您真的需要一个无法解决的最小问题示例。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。