非阻塞读取文件/获取文件描述符c ++

时间:2016-02-26 19:23:44

标签: c++ linux ifstream nonblocking file-descriptor

我创建的程序可以从不同的来源(命名管道和USB串行设备)获取信息。我可以用一个简单的ifstream成功做到这一点。但是现在我需要更改它以使读取无阻塞,因为数据稀疏且源提供数据的顺序是不可预测的。 位置源在启动时未知,但很快找到,之后不会更改。我用g ++编译,目标是覆盆子pi 2(带有raspbian)

经过一些研究后,我遇到了select()和poll()。问题是他们使用文件描述符。我发现获取文件描述符的次数很少。 我发现(fstream.rdbuf()) - > fd()但它没有编译(显然它不再受支持)

我能想到的一个可能的解决方案是将程序分成两部分: 一个搜索文件,然后使用bash启动程序2,并将正确的文件传入其中。 (例如,program2< 1 input1< 2 input 2 ...)。至少我认为这会起作用(我知道你可以重定向多个输出,所以我认为你可以重定向多个输入) 但它似乎是一个非常糟糕的解决方案(我需要一种能够从文件描述符中读取的方法(在ifstream中获取它))

我能想到的另一个解决方案是多线程。每个输入都有自己的线程,然后读取阻塞并不重要。当线程接收输入时,它需要唤醒主线程并传输数据。 这个解决方案似乎比前一个解决方案要好得多,但它似乎仍然不实用(这是正确的术语吗?)。我认为对于那些在c ++之前从未使用多线程的人来说这太复杂了,这可能会导致数小时的调试来修复问题,例如由多个线程同时发送数据引起的问题(除非c ++多线程更简单然后我认为它是)。

那么有什么其他方法可以解决这个问题(或者如果没有其他方法,我建议使用哪两种解决方案)。

英语不是我的母语,对任何错误都很抱歉。 这也是我在stackoverflow上的第一篇文章。 如果你想知道我对c ++的熟悉程度。我上学期间只学过c ++(虽然这是个人项目)。并且只编写了一个包含大约25个课程的项目(这是一个小组项目,另外3个人)。但我们学得很快,因为我们可以应用其他编程语言的大量知识。

2 个答案:

答案 0 :(得分:0)

C ++流不会暴露底层文件描述符(因为文件描述符是特定于操作系统的,并且流是通用的)。

您可以使用原始描述符并在其上编写自己的流(根本不是很难)。但是,您意识到async-io模型需要某些技能吗?你提到你是多线程新手,你曾经使用async io吗?

答案 1 :(得分:0)

Boost.Asio是一个Boost库,以跨平台的方式处理异步IO。它以C ++方式包装linux epoll 和windows IO完成端口

Casablanca是面向后端开发的跨平台Microsoft平台。他们走得更远,用伪无阻塞fstream对象包裹Boost.Asio。它的工作原理是将工作分成异步任务。

考虑到目前没有更好的解决方案,我会选择卡萨布兰卡。 另外,我确保该流没有任何异常locale,这通常会降低阅读效果。

PS。对于fstream性能,多线程解决方案听起来很有用。