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 library
fd1 bigger number. didn't change anything. - changed
maxfd
fd1
orfd2
in each select call (so select fd1+1 or fd2+1 depending on whether used catch read- or write-readiness) didn't change anything.