Search code examples
c++linuxifstreamnonblockingfile-descriptor

Non blocking read on files/getting file descriptors c++


I'm creating a program that get's information from different sources (named pipes and usb serial devices). I can successfully do that with a simple ifstream. But now I need to change it so the reads are non blocking, because the data is sparse and the order in which the sources provide data is unpredictable. The location sources are unknown at startup but are found quickly and do not change afterwards. I use g++ to compile and the intended target is a raspberry pi 2 (with raspbian)

After some research i came across select() and poll(). The problem is they use file descriptors. I found very little on getting the file descriptors. I found (fstream.rdbuf())->fd() but it doesn't compile (apparently it isn't supported anymore)

One possible solution I could think of is split the program into 2 parts: one that searches for the files, and then uses bash to start program 2 with the correct files piped into it. (eg program2 <1 input1 <2 input 2 ...). At least I think this would work (I know you can redirect multiple outputs so I presume you can do redirect multiple inputs) But it seems like a very bad solution (and I would need a way to be able to read from the file-descriptors as well (getting it in ifstream))

Another solution I could think of is to multi-thread. Each input gets their own thread and then it doesn't matter if the reads block. When a thread receives input, it would need to wake up the main thread and transfer the data. This solution seems much better than the previous one but it's still seems unwieldy (is this the correct term?). I think this would be too complex for someone who has never multi-threaded before in c++, and this would probably cause hours of debugging to fix problems eg caused by multiple threads sending data simultaneously (unless c++ multi-threading is simpeler then I think it is).

So what other ways are there to solve this problem (or if there are no others, which of my 2 solutions would be recommended).


English is not my native language, so sorry for any mistakes. This is also my first post on stackoverflow. If you want to know how familiar I am with c++. I only learned c++ last semester on my university (though this is a personal project). And only wrote one project with about 25 classes (this was a group project, with 3 other people). But we learned quickly because we could apply much knowledge from other programming languages.


Solution

  • C++ streams do not expose underlying file descriptors (because file descriptors are OS-specific, and streams are universal).

    You could use raw descriptors and write your own streams on top of it (not hard at all). However, you realize that async-io model requires certain skills? You are mentioning you are new to multithreading, have you ever worked with async io?