是否可以在stdout、stdin和stderr之外使用更多的流?
当然可以!在绝大多数操作系统(像Linux、Windows这类)里,进程完全支持创建和使用标准流之外的额外通信流,刚好能解决你现在遇到的串口数据过滤麻烦的问题。我给你几个贴合你场景的实用思路:
用自定义管道/套接字做进程间通信流
你可以给主进程和子进程创建额外的专属通信管道,或者用套接字来传递数据。比如在类Unix系统里,通过pipe()调用生成一对文件描述符,一端留在主进程,另一端传给子进程;Windows下也有匿名管道、命名管道可以用。这样你就能把串口收到的特定响应数据或者广播数据,直接分发到这些自定义流里,程序员的代码不用再去stdin里费劲过滤,直接从对应流里取数据就行,效率和清晰度都高很多。
如果需要多进程共享广播数据,命名管道或者Unix域套接字会更合适——多个进程都能连接到这个流,设备发的广播数据推进来后,所有需要的进程都能读取。主进程统一管理串口,分流数据到自定义流
最好让主进程独占串口的读写权限,避免主、子进程同时操作串口导致的数据混乱或者竞争问题。然后主进程负责把串口收到的数据分类:比如专门开一个流给子进程里需要等待响应的逻辑,另一个流处理广播数据。你可以在自己的库里封装好这些流的创建和管理API,比如给程序员提供get_response_stream()、get_broadcast_stream()这样的接口,让他们不用管底层的IPC细节,直接用这些流读写数据就行。扩展进程的文件描述符/句柄
其实stdin、stdout、stderr只是进程默认打开的3个文件描述符(编号0、1、2),系统允许进程打开更多的文件描述符,对应不同的流(管道、套接字、甚至普通文件都可以)。你完全可以创建这些额外的描述符,在主、子进程之间传递使用。比如Python里用subprocess.Popen的pass_fds参数就能把自定义描述符传给子进程;C/C++里fork之后子进程会继承父进程的打开描述符,只要记得关掉不需要的就行。
另外提个小建议:如果程序员的代码需要主动发数据到设备,也可以通过自定义流把数据传给主进程,再由主进程统一发送到串口,这样能彻底避免串口操作的并发冲突问题。
备注:内容来源于stack exchange,提问作者Radar32

