I have a listening thread that waiting for reading on few socket using select and FD_SET. The story is. At some point I will add another socket to the pool and need to abort select and re-initialize FD_SET array fo select. I have an Event to signal pool changes. But how select can react to my Event?
select() at this point of time use timeval with waiting interval of 20 sec and I don't want to changed time to lower value. I don't want frequently re-start select() by timeout...
Is there any way to abort select? What would be the right approach to inform/restart select and force using of new list of socket(at least one socket will be added to pool)
And another question - Msdn says "The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O."
Does that mean that select is not designed to work with sockets that turned to use using async operation?
Use WSAEventSelect() and WSAWaitForMultipleEvents() instead of select(). That way, your pool can create a separate event with WSACreateEvent() and signal it with WSASetEvent() to wake up WSAWaitForMultipleEvents() when needed.
If you want select() to wake up, the easiest way is to send a byte to one of the sockets that select() is waiting on for read access. One way to implement that without affecting functionality of the existing sockets is to create a pair of sockets specifically for that purpose and connect() one to the other.
Related
I am using the poll mechanism to manage upto 100 connections. Is there any standard practice for what the time out value for the poll() call should be or how to determine it.
My case details -
I have one dispatcher thread listening on all the connections. Once a connection becomes read ready, I disable it for polling and forward the connfd to a thread pool processing reads. The dispatcher thread goes back to polling.
The thread pool consumes the read on the connfd and posts it back to the dispatcher so it can add it for polling next. But the dispatcher wouldn't be able to add it for polling until it returns from the poll() call. I need the dispatcher to periodically check if it needs to re-enable polling for any connfd.
What is a good timeout value so the dispatcher thread can periodically stop polling and update its pollfd list.
You don't need to use the timeout (just set it to INF).
Timeout is basically used when an explicit timer operation is needed (some async IO libraries handles this for you).
To wake up a thread sleeping in poll, use the self-pipe trick. On Linux, eventfd is also available for use.
Using timerfd (Linux only), timeout can be completely obsoleted.
I am searching solution to wake-up select call in c++, As per application requirement i cant set timeout because of multiple thread using select system call.
Please see below scenario.
i want to wakeup select system call waiting on other thread. I tried to write data on the thread from main thread but still it is not able to wakeup it.
I want to close thread and socket if there is empty data on this thread.
It is wakes up select call if socket connection is close from other process, but not working with thread.
Does any one have idea regarding this
On a recent Linux you can use eventfd, on everything in general - a pipe, usage - register one side of the pipe in selector for readability along with actual socket(s), to wake up a selector - just write one byte to the other end of the pipe. Alternatively (if your libc has it) you can use pselect with a sigmask to catch the ALRM signal and raise that signal whenever you need to wake the selector up. Be very careful with using signals approach in a multithreaded application (as "I would not use"), as if not done right a signal may be delivered to a random thread.
Thanks all for valuable suggestion, I am able to resolve the issue with shutdown() call on socket FD using reference answer present on this link, it will pass wakeup signal to select, which is waiting for action. We should close socket only after select call otherwise select will not able to get wake up signal.
I'm working on a windows/unix multithreaded server application network layer with Berkeley sockets and stumbled upon a problem:
I have one thread waiting at select with given fd sets.
From another thread, I need to add a socket to one of the fd sets.
As the select is currently pending, it cannot be done and leads to a starvation.
Possible solution is to add a timeout to the select. I have seen that on sites addressing networking with select (dated 15 years back).
The question is:
Are there any other solutions? Waiting for timeout still leads to some level of starvation and takes CPU time from the select-waiter thread. I thought it would be possible to redesign the application but adding sockets is also done from threads that select-waiter thread has (and most definitely should have) no idea about, so the condition cannot be avoided.
If not, what sort of timeout should be chosen to achieve best performance / service quality?
Also note that I do realize that it would be better idea to use more advanced API (iocp, kqueue, ...) or a lib that would do it for me, but that is not an option for me at the given point.
Thanks
Create an additional socket pair and add one of these sockets to every select. To interrupt a running select, send a message to it via the other socket.
On the Unix side only, one can send any signal (e.g. SIGUSR1) to the waiting thread with pthread_kill. select with then return a negative value, and errno will be set to EINTR. But there is nothing like that on the Windows side.
On my journey to get a Software running under Windows and Linux, I had to rewrite the socket layer. On Windows I changed from select to WSAPoll and use a WSAWaitForMultipleEvents before including a standard event to cancel the operation before timeout when necessary. As I have to handle more than 1024 in and out sockets, I have to change from select to poll on linux to. Is there any way to cancel the wait on poll under linux. I have to add remoe connections, which will be slowed down by the wait timeout by the poll.
Create a pseudo internal event using pipe() and add the read side of this to the poll() list, making it the first event.
When you want to cancel the poll write a character to the pipe and poll() will return. You will know it's an internal event as it will have index 0.
You can even make this a crude messaging system by passing different values down the pipe.
You can do the same this with your Windows code using a manual event.
See this IoEvent class that does just that.
In my program there is one thread (receiving thread) that is responsible for receiving requests from a TCP socket and there are many threads (worker threads) that are responsible for processing the received requests. Once a request is processed I need to send an answer over TCP.
And here is a question. I would like to send TCP data in the same thread that I use for receiving data. This thread after receiving data usually waits for new data in select(). So once a worker thread finished processing a request and put an answer in the output queue it has to signal the receiving thread that there are data to send. The problem is that I don't know how to cancel waiting in select() in order to get out of waiting and to call send() .
Or shall I use another thread solely for sending data over TCP?
Updated
MSalters, Artyom thank you for you answers!
MSalters, having read your answer I found this site: Winsock 2 I/O Methods and read about WSAWaitForMultipleEvents(). My program in fact must work both on HP-UX and Windows I finally decided to use the approach that had been suggested by Artyom.
You need to use something similar to safe-pipe trick, but in your case you need to use a pair of connected TCP sockets.
Create a pair of sockets.
Add one to the select and wait on it as well
Notify by writing to other socket from other threads.
Select is immediately waken-up as one of the sockets is readable, reads all the
data in this special socket and check all data in queues to send/recv
How to create pair of sockets under Windows?
inline void pair(SOCKET fds[2])
{
struct sockaddr_in inaddr;
struct sockaddr addr;
SOCKET lst=::socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
memset(&inaddr, 0, sizeof(inaddr));
memset(&addr, 0, sizeof(addr));
inaddr.sin_family = AF_INET;
inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
inaddr.sin_port = 0;
int yes=1;
setsockopt(lst,SOL_SOCKET,SO_REUSEADDR,(char*)&yes,sizeof(yes));
bind(lst,(struct sockaddr *)&inaddr,sizeof(inaddr));
listen(lst,1);
int len=sizeof(inaddr);
getsockname(lst, &addr,&len);
fds[0]=::socket(AF_INET, SOCK_STREAM,0);
connect(fds[0],&addr,len);
fds[1]=accept(lst,0,0);
closesocket(lst);
}
Of course some checks should be added for return values.
select is not the native API for Windows. The native way is WSAWaitForMultipleEvents. If you use this to create an alertable wait, you can use QueueUserAPC to instruct the waiting thread to send data. (This might also mean you don't have to implement your own output queue)
See also this post:
How to signal select() to return immediately?
For unix, use an anonymous pipe. For Windows:
Unblocking can be achieved by adding a dummy (unbound) datagram socket to fd_set and then closing it. To make this thread safe, use QueueUserAPC:
The only way I found to make this multi-threadsafe is to close and recreate the socket in the same thread as the select statement is running. Of course this is difficult if the thread is blocking on the select. And then comes in the windows call QueueUserAPC. When windows is blocking in the select statement, the thread can handle Asynchronous Procedure Calls. You can schedule this from a different thread using QueueUserAPC. Windows interrupts the select, executes your function in the same thread, and continues with the select statement. You can now in your APC method close the socket and recreate it. Guaranteed thread safe and you will never loose a signal.
The typical model is for the worker to handle its own writing. Is there a reason why you want to send all the output-IO through selecting thread?
If you're sure of this model, you could have your workers send data back to the master thread using file descriptors as well (pipe(2)) and simply add those descriptors to your select() call.
And, if you're especially sure that you're not going to use pipes to send data back to your master process, the select call allows you to specify a timeout. You can busy-wait while checking your worker threads, and periodically call select to figure out which TCP sockets to read from.
Another quick&dirty solution is to add localhost sockets to the set. Now use those sockets as the inter-thread communication queues. Each worker thread simply sends something to its socket, which ends up on the corresponding socket in your receiving thread. This wakes up the select(), and your receiving thread can then echo the message on the appropriate outgoing socket.