What is the issue of select() using so much CPU power? [closed] - sockets

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am writing a network communication program using non-blocking sockets (C/C++) and select. The program is pretty big, so I cannot upload source code. In a very aggressive testing session, I use testing code to open and close both TCP and UDP frequently. It always ends up that one end does not respond and has CPU usage over 98 or 99%. Then I use gdb to attach. "bt" shows the following:
0x00007f1b71b59ac3 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:82
82 ../sysdeps/unix/syscall-template.S: No such file or directory.
in ../sysdeps/unix/syscall-template.S
What type of error could it be?
$ uname -a
Linux kiosk2 2.6.32-34-generic #77-Ubuntu SMP Tue Sep 13 19:39:17 UTC 2011 x86_64 GNU/Linux

It's impossible to say without looking at the code, but often when a select-based loop starts spinning at ~100% CPU usage, it's because one or more of the sockets you told select() to watch are ready-for-read (and/or ready-for-write) so that select() returns right away instead of blocking... but then the code neglects to actually recv() (or send()) any data on that socket. After failing to read/write anything, your event loop would try to go back to sleep by calling select() again, but of course the socket's data (or buffer space, in the ready-for-write case) is still there waiting to be handled, so select() returns immediately again, the buggy code neglects to do the recv() (or send()) again, and around and around we go at top speed :)
Another possibility would be that you are passing in a timeout value to select() that is either zero or near-zero, causing select() to return very quickly even when no sockets are ready-for-anything... that often happens when people forget to re-initialize the timeval struct before each call to select(). You need to re-initialize the timeval struct each time because some implementations of select() will modify it before returning.
My suggestion is to put some printf's (or your favorite equivalent) immediately before and immediately after your call to select(), and watch that output as you reproduce the fault. That will show you whether the spinning is happening inside of a single call to select(), or if something is causing select() to return immediately over and over again.

Related

Perl improve performance of generating 1 pixel image [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Hi I need to generate a 1x1 pixel image in perl, what can be the fastest way to generate this. Assuming i will be getting 10K connections/per second on my web server.
Currently i am using this :
print MIME::Base64::decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABGdBTUEAALGPC/xhBQAAAAZQTFRF////AAAAVcLTfgAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH0gQCEx05cqKA8gAAAApJREFUeJxjYAAAAAIAAUivpHEAAAAASUVORK5CYII=
I cannot host a static file, as we need to process the request for some data.
Thanks
Kathiresh Nadar
First off, for high performance perl you should be using fastcgi (via the FCGI module directly, or the CGI::Fast wrapper) or mod-perl or some other technology to make your script stick around as a persistent process in memory.
Secondly, if you're processing the request for some other data first and that involves anything like writing to a file or talking to a database or something like that, your time will be dominated by that processing. Generating the image is not the slow part.
But let's answer your question anyway: assuming that you are using some keep-the-script-in-memory technology, then the first thing you can do is move your MIME::Base64::decode call to a BEGIN block, store the result in a variable, and use that variable.
But also, sending the image over the wire is likely going to take longer than the processing on the server, so why are you sending 167 bytes of PNG when you could be sending 42 bytes of GIF? Put both of those pieces of advice together, and you get:
my $gifdata;
BEGIN { $gifdata = MIME::Base64::decode(
"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); }
print $gifdata;

how libevent detect that a socket is closed

if I add an event for a specific socket to event loop,
for example, a TCP connection socket.
then it may happen that the socket is closed,
then how will libevent act?
can it detect this?
thanks!
EDIT: I think I misinterpreted your question at first.
If you mean that the socket is closed from the remote end
As per the documentation you can use the event_new() and event_add() calls to register interest in a socket. Make sure you specify EV_READ since you are interested in when the socket is closed.
Remember that there is no difference in file descriptor readiness between data available for reading and a closed socket. Normally you must read the socket to find out which condition is true, but if you don't want to read the socket then you can look here for a hint.
If you mean that the socket is locally closed (the file descriptor was closed
Using a file descriptor after it has been closed is never defined and can always lead to undefined results. This is not specific to libevent. Before you close a file descriptor, you must make sure that no other thread in your program is using it, and you must make sure that no other part of your program is going to try using it in the future. That means unregistering the file descriptor from libevent at the same time that you close it.

Shutdown Persistent TCP Con. (C multithreaded server)

I'm designing a multi-threaded server with a thread pool. This system is designed to use persistent TCP connections, as clients will maintain connects close to 24/7. The problem I run into is how to manage shutdowns. Currently, a connection comes in through "accept(listen_fd....)" and gets assigned to a work order struct. This struct is dumped onto the work queue, and is picked up by a thread. From this point on, this thread is devoted to the current connection. My code inside the thread is:
/* Function which runs in a thread to handle a request */
void *
handle_req( void *in)
{
ssize_t n;
char read;
/* Convert the input to a workorder_ptr */
workorder_t *workorder_ptr = (workorder_t *)in;
while( !serv_shutdown
&& (n=recv(workorder_ptr->sock_fd,&read,1,0) != 0))
{
printf("Read a character: %c\n",read);
}
printf("Peer has shutdown.\n");
/* Free the workorder memory */
close(workorder_ptr->sock_fd);
free(workorder_ptr);
return NULL;
}
Which simply listens to the socket and echos the characters indefinitely, and operates correctly when the client terminates the connection. You see the "!serv_shutdown" part in the while loop - this is my attempt to get the thread to break out of its loop on a shutdown signal. When a SIGINT is caught, the global variable is set to 1. Unfortunately, the program is currently blocking on the recv statement, and won't check this flag until another character is read. I want to avoid that, since it could be an arbitrary amount of time before another character is sent on this connection.
Also, I read on another post here that it's better to use "select" than "accept" to wait on a socket connection, but I didn't quite understand. Would you do a select to wait, and then do an accept right after that? I'm not sure how select creates a socket connection. I ask this, because if my understanding of select is cleared up, maybe it applies to the question I am asking?
Also also, how do I detect the case where a connection simply times out?
Thanks!
EDIT
I think I may have finally found a solution, after further digging:
Wake up thread blocked on accept() call
Basically, I could create a global pipe and have each thread do a select on its own socket_fd as well as this global pipe. Then, when a signal is caught, I'll just write something to the pipe. All threads should be woken, no?
Well, on FreeBSD, MacOSX and maybe somewhere else there is kevent() call, that allows listening on a broad range of system events including connect requests and signaling when data arrives to the socket.
It will solve all of your problems in a neat way, but it's not portable. There are libs such libevent and libev, that wraps OS-specific functionality like kevent() on BSD's, epoll() on Linux and so on. May be it would help you.
You can use the recv() primitive. If it returns 0, that means that the socket has been closed.
More information: http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#recvman

An IOCP documentation interpretation question - buffer ownership ambiguity

Since I'm not a native English speaker I might be missing something so maybe someone here knows better than me.
Taken from WSASend's doumentation at MSDN:
lpBuffers [in]
A pointer to an array of WSABUF
structures. Each WSABUF structure
contains a pointer to a buffer and the
length, in bytes, of the buffer. For a
Winsock application, once the WSASend
function is called, the system owns
these buffers and the application may
not access them. This array must
remain valid for the duration of the
send operation.
Ok, can you see the bold text? That's the unclear spot!
I can think of two translations for this line (might be something else, you name it):
Translation 1 - "buffers" refers to the OVERLAPPED structure that I pass this function when calling it. I may reuse the object again only when getting a completion notification about it.
Translation 2 - "buffers" refer to the actual buffers, those with the data I'm sending. If the WSABUF object points to one buffer, then I cannot touch this buffer until the operation is complete.
Can anyone tell what's the right interpretation to that line?
And..... If the answer is the second one - how would you resolve it?
Because to me it implies that for each and every data/buffer I'm sending I must retain a copy of it at the sender side - thus having MANY "pending" buffers (in different sizes) on an high traffic application, which really going to hurt "scalability".
Statement 1:
In addition to the above paragraph (the "And...."), I thought that IOCP copies the data to-be-sent to it's own buffer and sends from there, unless you set SO_SNDBUF to zero.
Statement 2:
I use stack-allocated buffers (you know, something like char cBuff[1024]; at the function body - if the translation to the main question is the second option (i.e buffers must stay as they are until the send is complete), then... that really screws things up big-time! Can you think of a way to resolve it? (I know, I asked it in other words above).
The answer is that the overlapped structure and the data buffer itself cannot be reused or released until the completion for the operation occurs.
This is because the operation is completed asynchronously so even if the data is eventually copied into operating system owned buffers in the TCP/IP stack that may not occur until some time in the future and you're notified of when by the write completion occurring. Note that with write completions these may be delayed for a surprising amount of time if you're sending without explicit flow control and relying on the the TCP stack to do flow control for you (see here: some OVERLAPS using WSASend not returning in a timely manner using GetQueuedCompletionStatus?) ...
You can't use stack allocated buffers unless you place an event in the overlapped structure and block on it until the async operation completes; there's not a lot of point in doing that as you add complexity over a normal blocking call and you don't gain a great deal by issuing the call async and then waiting on it.
In my IOCP server framework (which you can get for free from here) I use dynamically allocated buffers which include the OVERLAPPED structure and which are reference counted. This means that the cleanup (in my case they're returned to a pool for reuse) happens when the completion occurs and the reference is released. It also means that you can choose to continue to use the buffer after the operation and the cleanup is still simple.
See also here: I/O Completion Port, How to free Per Socket Context and Per I/O Context?

Winsock Select() function gives 0xC00000FD exception

I've a select based server. Sockets are in blocking mode,but for select() function I'm using 250 ms. timeout.
Basically my server accepts only one client and sending data to that client.
It is working for weeks without problem if I just send data from server to client.
But I realized that if client sends data to server after 3-4 hours at the select() line it gives stack overflow exception (0xC00000FD).
I red dozens of times MSDN page of Select(), but nothing mentioned related to this.
I'm really stuck. Any help will be appreciated.
By the way, I found on the net, example;
http://tangentsoft.net/wskfaq/examples/basics/select-server.cpp
here after accepting client connection, he is setting it to nonblocking mode.
And it is commented that;
// Mark the socket as non-blocking, for safety.
What does "safety" means above?
So do you think is this my problem? Because in my implementation, connected ones are in blocking mode?
Thanks in advance
An exception means there is a bug in your code. Since you are getting a stack overflow, you likely have a recursive loop in your code that is running too long, eating up stack space on each call until there no more stack space left. Under normal conditions, select() returns an error code when it fails, so you have to be messing up your program's memory somewhere to be getting an exception.