c++ - File descriptor set and selection understanding - unexpected behaviour -
i have third party library kind of shared memory (between processes) implementation preset number of memory buffers.
processes divided reading , writing.
this library gives file-descriptor each process.
i wanted test functionality, using code sample (single process divided reading , writing functionality) provided library. code sample worked, wanted understand file descriptors , how work.
this basic code sample (reduced , commented me) (uses 4 shared buffers):
int fd1, fd2; // 2 file descriptors, fd1 writing , fd2 reading sharedmemory_getdescriptor(&fd1, options1); // options1 tells library fd1 used writing data sharedmemory_getdescriptor(&fd2, options2); // options2 tells library fd2 used reading data fd_set readset, writeset; // fd_sets later select commands // empty sets fd_zero(&readset); fd_zero(&writeset); // find out whether writer may write fd_set(fd1, &writeset); fd_set(fd2, &readset); // why has 1 set?? // test sets "ready read or write" select(maxfd+1, &readset, &writeset, null, &timeout); // maxfd 1 bigger fd1 , fd2, timeout small time value... // if fd1 ready write, can if (fd_isset(fd1, &writeset)) { if (sharedmemory_getbuffer(&buffer1) == s_ok) { [...] // write values buffer provided shared memory sharedmemory_releasebuffer(&buffer1); // tell library, buffer written?!? } } // if repeat steps fd_set(fd1, writeset)->select->fd_isset(fd1, &writeset)->fillbufferandrelease, // fd_isset fails 5th buffer, since have 4 buffers. result expected , works. // try read data using second file descriptor fd2 // add fd2 readset fd_set(fd2, &readset); // test whether fd2 ready read select(maxfd+1, &readset, null, null, &timeout); if (fd_isset(fd2, &readset)) { if (sharedmemory_getbuffer(&buffer2) == s_ok) { [...] // read data buffer provided shared memory sharedmemory_releasebuffer(&buffer2); // tell library, buffer read?!? } } this works expected, can write 1-4 buffers , later read 1-4 buffers. additionally can e.g. first write 1 buffer, read one, write 1 , on.
but there didn't expect. understanding, before writing data in beginning,
fd_set(fd1, &writeset); fd_set(fd2, &readset); select(maxfd+1, &readset, &writeset, null, &timeout); could reduced
fd_set(fd1, &writeset); select(maxfd+1, null, &writeset, null, &timeout); because i'm neither interested in readset before write data, nor fd2 still in readset after select returns.
but if change select(maxfd+1, null, &writeset, null, &timeout); or if remove fd_set(fd2, &readset);, select before reading part waits until timeout , fd2 isn't present in readset anymore.
what can reasons that? far seem understand, whether fd1 , fd2 ready-to-write or ready-to-read depends on state of extern library. why library state change when locally add fd2 set , ask being ready-to-read isn't?
or misunderstanding concerning file-descriptors , select?? noob in topic , couldn't find information/tutorials.
edit:
tried more things:
- added single
fd_set(fd2, &readset); select(fd2+1, &readset, null, null, &timeout);before first writeset-select , removed readset part first writeset-select. did work, doesn't answer question in ways. - changed order of
getting descriptors libraryfd1 bigger number. didn't change anything. - changed
maxfdfd1orfd2in each select call (so select fd1+1 or fd2+1 depending on whether used catch read- or write-readiness) didn't change anything.