Reputation: 1267
I don't have much experience with asynchronous I/O on sockets. Recently I had to implement a TCP client that would connect to a server in a seperate thread and wait for input data and that in a non-blocking manner so that the thread could be terminated immediately by simply setting some flag varaible from the control thread. My solution was setting socket non-blocking and implementing a loop that called recv over and over again if errno was E_WOULDBLOCK and exited loop when flag variable run wasn't set anymore. It was like that:
while(run) {
if( -1 == recv(...))
{
if(errno == E_WOULDBLOCK)
continue;
else
break;
}
else
{
process_data(...);
}
}
The question is: how good is this solution in terms of CPU usage? Will using select/poll/epoll be more effective?
And another one question: is there any way to make blocked select, read or connnect call return immediately from other thread?
Upvotes: 0
Views: 1865
Reputation: 8494
The question is: how good is this solution in terms of CPU usage? Will using select/poll/epoll be more effective?
It is terribly inefficient. It is probably the worst way you handle multiple connections.
Consider that each recv
is a system call: it requires a context switch. A context switch is not expensive, but computing a context switch in a high frequency loop will likely full the CPU usage.
Also, if you were to sleep between a call and another, to "soften the loop", you would end up paying a delay between data receive and processing; the more connections you have, the higher it'll be felt.
select
basically tells the kernel: "I want these sets of fds to be monitored by you and also be signaled as soon as something happens.". Your process will enter a waiting state and become ready when an event is delivered. Meanwhile, the CPU may serve other processes.
You may use a blocking multiplexer and handle each work in a separate thread (maybe from a thread pool), which is very efficient. But it depends on what you're doing.
And another one question: is there any way to make blocked select, read or connnect call return immediately from other thread?
Well, yes. But is something you want to have? As @alk said, you can send them a signal. In addition, for recv
and connect
, you might want to use select
/poll
or any other multiplexer with timeout properties; it might be harder to program, though.
Upvotes: 2
Reputation: 70903
how good is this solution in terms of CPU usage?
Busy waiting is very inefficient.
Will using
select
/poll
/epoll
be more effective?
Yes.
is there any way to make blocked
select
,read
orconnnect
return immediately
Yes, send the blocked thread a signal. The function in question will return -1
and errno
shall be set to EINTR
. When setting up the signal handler take care of how SA_RESTART
is handled by your compiler's implementation.
Upvotes: 2
Reputation: 25409
Assuming you are programming in C and have a decent kernel version, pselect
is the way to go.
Waiting for input and signals simultaneously is a well-known problem and there are many good discussions about the problems and solutions associated with it. You might find this discussion a good start.
Upvotes: 0