我阅读了tokio文档,我想知道将来封装昂贵的同步I/O的最佳方法是什么.
使用reactor框架,我们可以获得绿色线程模型的优势:一些OS线程通过执行程序处理大量并发任务.
未来的tokio模型是需求驱动的,这意味着未来本身将轮询其内部状态以提供有关其完成的信息; 允许背压和取消功能.据我了解,未来的投票阶段必须是非阻塞才能运作良好.
I/OI想要封装可以看作是一个长期的原子和昂贵的操作.理想情况下,独立任务将执行I/O,并且相关联的未来将轮询I/O线程以获得完成状态.
我看到的两个唯一选择是:
poll在将来的功能中.据我所知,这两种解决方案都不是最优的,并且没有充分利用绿色线程模型(首先不在文档中建议,其次不通过reactor框架提供的执行程序).还有其他解决方案吗?
我想知道将数据从gRPC服务器推送到客户端是否是一个好主意.基本上我想使用gRPC的pub/sub模式.我这样做的方法是在服务器实现上返回一个我从未关闭的响应流.然后,客户端有一个永无止境的例程负责读取此流.
这是一个例子:
service Service {
rpc RegularChanges (Void) returns (stream Change) {}
}
Run Code Online (Sandbox Code Playgroud)
在服务器端:
func (self *MyServiceImpl) RegularChanges(in *pb.Void, stream pb.Service_RegularChangesServer) error {
for {
d, err := time.ParseDuration("1s")
if err != nil {
log.Fatalf("Cannot parse duration")
break;
}
time.Sleep(d)
stream.Send(&pb.Change{Name:"toto", Description:"status changed"})
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
在客户端:
for {
change, err := streamChanges.Recv()
if err != nil {
log.Fatalf("Error retrieving change")
} else {
log.Println(change)
}
}
Run Code Online (Sandbox Code Playgroud)
我刚开始使用go和gRPC,但我知道它基于HTTP2,因此它应该支持推送数据.但是,我不确定这是否应该使用gRPC.
在fish shell中执行这些命令时
$ mkfifo answer
$ nc -vv -l -k -p 8001 <answer | tee -a answer
Run Code Online (Sandbox Code Playgroud)
命令挂起。
如果我写answer通过echo "" > answer. 然后nc恢复并开始正确收听。
如果与挂起过程相反CTRL-C,则消息如下:
^C<W> fish: An error occurred while redirecting file 'answer'
open: Interrupted system call
Run Code Online (Sandbox Code Playgroud)
另一方面,在 bash 中执行时:
$ mkfifo answer
$ nc -vv -l -k -p 8001 <answer | tee -a answer
Run Code Online (Sandbox Code Playgroud)
该命令不会挂起并直接开始侦听。
Fish 和 bash 中发生了什么不同的情况来解释这种不同的行为?