How to read a maximum of X seconds in C ++?

I want my program to expect something to read in FIFO, but if read (I use std::fstream ) lasts more than 5 seconds, I want it to exit.

Is it possible, or should I use alarm absolutely?

Thanks.

+4
source share
2 answers

I do not believe that there is a clean way to do this, it is a portable solution in C ++. It is best to use poll or select on * nix and WaitForSingleObject or WaitForMultipleObjects systems on Windows.

You can do this transparently by creating a streambuffer proxy class that forwards calls to the real streambuffer object. This will allow you to call the appropriate wait function before doing the actual read. It might look something like this ...

 class MyStreamBuffer : public std::basic_streambuf<char> { public: MyStreamBuffer(std::fstream& streamBuffer, int timeoutValue) : timeoutValue_(timeoutvalue), streamBuffer_(streamBuffer) { } protected: virtual std::streamsize xsgetn( char_type* s, std::streamsize count ) { if(!wait(timeoutValue_)) { return 0; } return streamBuffer_.xsgetn(s, count); } private: bool wait() const { // Not entirely complete but you get the idea return (WAIT_OBJECT_0 == WaitForSingleObject(...)); } const int timeoutValue_; std::fstream& streamBuffer_; }; 

You will need to do this with every call. This may be a little tedious, but it will provide a transparent solution for providing timeouts, even if they cannot be explicitly supported in client code.

+1
source

For the one I helped solve the problem, here is my read function from my stream. I could not finally use std::fstream , so I replaced it with C system calls.

 std::string NamedPipe::readForSeconds(int seconds) { fd_set readfs; struct timeval t = { seconds, 0 }; FD_ZERO(&readfs); FD_SET(this->_stream, &readfs); if (select(this->_stream + 1, &readfs, NULL, NULL, &t) < 0) throw std::runtime_error("Invalid select"); if (FD_ISSET(this->_stream, &readfs)) return this->read(); throw NamedPipe::timeoutException(); } 
0
source

All Articles