背景&目标
开发一个程序交互接口:
- 可使用Julia异步、后台启动一个命令/exe文件
 - 支持在运行时向程序异步写入命令、读取输出(文本IO)
 - 支持调用函数关闭程序,关闭程序进程
 - 支持对多个进程的并行、异步调度(e.g. 同时启动多个cmd shell,用户可以指定「向哪一个cmd shell读写输入/输出」)
 
问题
在「读取输出」的过程中,遇到「read没有输出导致主进程死循环阻塞」的问题
- 函数
read/readline/readlines均无法识别「输出是否完整」 - 主进程阻塞后,除非使用
Ctrl+C强行停止,代码无法自行执行完毕,后续对程序的IO操作无法继续执行 
MWE
proc = open(`cmd`, write=true, read=true) # 后台异步打开一个cmd进程
println(proc, "echo 1") # 使用println输入指令
@show readline(proc) # 输出「"readline(proc) = 【cmd路径】> echo 1"」
@show readline(proc) # 输出「"readline(proc) = 1"」
@show readline(proc) # REPL/Debugger/.jl脚本 无响应:主进程阻塞,程序卡死
# 或:使用循环从指令中获取输入(及其应答)
for l in readlines(proc)
       @show l
       end
# 此后主进程阻塞,程序卡死 #
预期:执行前eof(proc) == true、执行时报错 或 执行后返回空值
实际:主进程阻塞,无法继续执行代码
在REPL运行上述代码直至卡顿后,使用Ctrl+C强制关闭的报错信息:
ERROR: InterruptException:
Stacktrace:
  [1] poptask(W::Base.IntrusiveLinkedListSynchronized{Task})
    @ Base .\task.jl:974
  [2] wait()
    @ Base .\task.jl:983
  [3] wait(c::Base.GenericCondition{Base.Threads.SpinLock}; first::Bool)
    @ Base .\condition.jl:130
  [4] wait
    @ .\condition.jl:125 [inlined]
  [5] readuntil(x::Base.PipeEndpoint, c::UInt8; keep::Bool)
    @ Base .\stream.jl:1014
  [6] readuntil(io::Base.Process, arg::UInt8; kw::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:keep,), Tuple{Bool}}})
    @ Base .\io.jl:442
  [7] readuntil
    @ .\io.jl:442 [inlined]
  [8] readline(s::Base.Process; keep::Bool)
    @ Base .\io.jl:548
  [9] readline(s::Base.Process)
    @ Base .\io.jl:547
 [10] top-level scope
    @ REPL[28]:1
=#
已参考过的问题/话题
- 【中】请问Julia如何与外部程序互传数据?不是读写文件的那种
使用"r+"与设置「write=true, read=true」等价:无法解决问题
 - 【英】Run commands on externally running process - General Usage - Julia Programming Language — 在外部运行进程上运行命令
运行read(pstdout)仍会遇到上述问题
 - 【英】Processing output from long running process - New to Julia - Julia Programming Language — 处理长时间运行的进程的输出
遍历eachline仍会遇到上述问题
 - 【英】 How to continuously communicate with an external program? - General Usage - Julia Programming Language — 如何与外部程序持续通信?
命令加上前缀stdbuf -oL仍会遇到上述问题