Select () does not recognize changes through FD_SET when locking

I call FD_SET () to set write_fd to a non-blocking socket, while select () blocks inside another thread - the problem is that select () blocks even if fd is ready to write.

What I really want to do is: Prepare the data for writing for this socket in another thread, after which I add the socket to write_fd. The select () stream must recognize and process prepared data.

Doesn’t highlight () recognition of changes inside fd when locking? If so, is there something like epoll () EPOLL_CTL_MOD instead of FD_SET () to update the set; or is the only way to recognize changes to set the timeout for the select () function?

In my opinion, this would not be a solution, because it would be "slow" and would create processor overhead ...

EDIT:

// This thread is running all day long ... static void * workman() { FD_ZERO(&fd_read); FD_ZERO(&fd_write); FD_SET(socketId , &fd_read); while(1) { // PROBLEM Keeps blocking when box() is called select(socketId+1, &fd_read, &fd_write, NULL, NULL); if(FD_ISSET(socketId, &fd_read)) { // RECIVE DATA } else if(FD_ISSET(socketId, &fd_write)) { FD_CLR(socketId, &fd_write); pthread_mutex_lock(&interface.mutex); strncpy(conn.outBuffer, interface.buffer, strlen(interface.buffer)); interface.buffer[0] = '\0'; pthread_mutex_unlock(&interface.mutex); // SEND DATA } } return 0; } // This function is called within another thread on user input int box(char *content) { pthread_mutex_lock(&interface.mutex); // preparing the data and write it into interface.buffer if available pthread_mutex_unlock(&interface.mutex); FD_SET(socketId, &fd_write); return 0; } 
+4
source share
2 answers

Yes, as you suspect, select() will not detect changes made to the set of file descriptors from another stream. In the end, he cannot do this efficiently without some magic mechanism for asynchronously detecting entries in specific memory locations.

And yes, you should use the epoll interface. The epoll_wait specifically notes that changes from another thread are being processed.

While one thread is blocked when calling epoll_pwait (), it is possible for another thread to add a file descriptor to wait for an instance of the era. If a new file descriptor is ready, it will call epoll_wait () to unlock.

But if you cannot use epoll or another file notification interface that supports such changes, there is still a solution. You can use an internal pipe (or similar mechanisms like eventfd ) so that select returns and restarts after updating sets of file descriptors. Of course, you must be careful to make the right lock to avoid race conditions. In the same way, do not forget to put the pipe in non-blocking mode, or write to the end of the pipe recording may be blocked under heavy load and, possibly, block your program.

+4
source

To do something like this, select, you will need an internal poll with the "current" set of fd, which will really be the processor overhead core, and you will not be able to control the polling period. This is what I think.

0
source

Source: https://habr.com/ru/post/1493032/


All Articles