   socket polling loop
  I''ve already asked this question in another thread, but then i thought that this question is worth starting a new thread...How to make write operations non-blocking properly, without wasting CPU resources?What i mean is:The basic loop for handling read events pending to be handled on a socket (or an array of sockets) looks like this:while (should_execute){poll_sockets();if (got_data_to_be_received) receive_data();if (got_incoming_connections) process_connection_requests();}select(), poll() and kqueue() behave the similar way when monitoring the sockets for readability, but what with writing?When watching the sockets for writeability, the mentioned functions usually return immediately, because inner socket buffers only become full in rare cases... Usually there''s always some inner buffer space available, so running this loop:while (should_execute){poll_socket_for_readability_and_writeability();if (got_data_to_be_received) receive_data();if (got_incoming_connections) process_connection_requests();if (can_send_data && got_data_to_be_sent) send_data();}will result in 100% CPU load, because the polling function returns immediately (not always, but in most cases)...We could add some code to block the networking thread (artificially pause it), for example:while (should_execute){poll_for_readability_and_writeability_with_zero_timeout(); // this will return immediatelyif (got_data_to_be_received) receive_data();if (got_incoming_connections) process_connection_requests();if (can_send_data && got_data_to_be_sent) send_data();sleep_for_some_amount_of_time();}but suspending the execution of the thread in such a manner is a bad idea, i suppose, because it damages scalability when server is under high load...So... how do i perform non-blocking write operations properly? 
  The whole point of non-blocking sockets is to avoid those tight loops. Worker threads and non-blocking sockets are mutually exclusive.All I can say is that I use non-blocking sockets in a single threaded application, by calling server.Update() every time through the app''s main loop. If the server has nothing to do, it does nothing. If it has something to do, it does it. That''s the beauty of non blocking - it returns immediately if there''s nothing to do. ;  foofightr, well, that''s true if you''re creating a quite simple server, but that is absolutely wrong if you''re trying to create a MMOG server... those usually run on multiprocessor machines, and running only one thread on such machine doesn''t scale good and is inefficient. You can achieve better performance on a multiprocessor machine if you create several worker threads (which handle ingame logic) + several networking threads (which would only handle network i/o and pass data to the worker threads).Even if you''re creating a simple server, the basic loop would look like this:while (should_execute){poll_for_readability_and_writeability_with_zero_timeout(); // this will return immediatelyif (got_data_to_be_received) receive_data();if (got_incoming_connections) process_connection_requests();if (can_send_data && got_data_to_be_sent) send_data();process_game_events(); // ... and other server-related stuff}so even when using a single thread this loop eats 100% CPU because it takes CPU time to iterate the loop even if there''s no data to be handled/processed... how to do that properly? ;  I think you should lock the the server to run this loop x times per second since the server should perform as good in all situations (no matter if there are 10 person logged in or 10 000).so sleep for the time you want the whole loop to take - the time it took for the code to execute.   [edited by - keen on February 3, 2004 2:50:02 PM];  keen, at the beginning i was thinking of implementing a solution similar to what you described, but then i realized, that it is a bad idea to sleep for a constant time, because it does not scale as the amount of connections grows...Or, i may be misunderstanding something... can you explain it in detail? ;  If you can thread this loop you can put the thread on a lower priority.Or you can use a Sleep for a variable period of time, depending on the nr of clients. Or as Keen suggested, you can time the time it takes the function to retrieve all data (call this POLLTIME). Then you say that you poll the clients 50 times each second, thus you allow the loop to take 20 ms.You time the function time (POLLTIME) and subtract POLLTIME from the 20 (1000/POLLS_PER_SECOND). For example you take 10 ms polling all sockets, then you have to sleep 10 more ms... if you poll for 15 ms, then you sleep 5 ms.In another topic (down the topic page) I asked how networking of FPS games worked, and I learned that they use a fixed nr of "polls" or "frames" per second. I think you can use this concept too for RPGs. ;quote:Original post by roookie  while (should_execute){poll_for_readability_and_writeability_with_zero_timeout(); // this will return immediatelyif (got_data_to_be_received) receive_data();if (got_incoming_connections) process_connection_requests();if (can_send_data && got_data_to_be_sent) send_data();process_game_events(); // ... and other server-related stuff}Roookie, you need to look a little bit more at completion port notifications and how they work.  This loop you''ve posted is NOT how you handle a MMOG server network.You *could* write a network system the way you describe, with the if statements, but you aren''t going to handle 10,000 players that way.  You''d be doing good to handle a few hundred like that   What you have there is pretty much equivelent to the FDSET model, which isn''t high up on the list of best performing networking models.  With completion notifications, you don''t poll the individual buffers for readability or writability (which is going to require a couple thousand polls), you let them tell you when their ready by posting a completion notification to a common port, and you just poll this single completion port in a tight loop (and in a seperate thread from any server game processing).  This is a much more efficient method and how every MMOG you know works (or they should anyway, I''d be very surprised if they didn''t  ).Look up IOCP in the gamedev forums.  They''re Windows specific, but there is an equivelent model (I believe) for straight Berkley sockets if you are going for some sort of *nix for your server.Ron ;  RonHiller, i''m aiming on UNIX, there''s no IOCP equivalent under UNIX, but there is the kqueue() kernel call, a universal event notification method, which scales good for thousands of connections and performes extremely fast...Structural, i don''t think that fixed server "fps" is a good idea for a MMOG...  ;quote:Original post by roookie  RonHiller, i''m aiming on UNIX, there''s no IOCP equivalent under UNIX, but there is the kqueue() kernel call, a universal event notification method, which scales good for thousands of connections and performes extremely fast...Sounds like the same concept to me   A universal event notification is exactly what the IOCP model is doing via a port (the "event" being a buffer read or write completion).  I dunno, I never use the *nixes, so my knowledge here is second hand, but I''ve been told they have an IOCP equivelent (and that sounds like it), so it seems to me that''s where your starting point ought to be.I can tell you for sure there is no way you can individually poll every buffer like you''re trying to do and keep it viable for a multi-thousand user game. Your loop needs two changes to make it scaleable.  One is to use a notification port (or the *nix equivelent) and two is to remove the game processing from the polling loop.  That has no business being there.The polling thread has one job and one job only, to poll for a completion notification, and if found, dump the corresponding buffer into a queue for the game processing thread to deal with.  Your polling thread must be *tight*.  Poll, dump the completed thread, and immediatly poll again as fast as you can.  If it''s a completed read, you dump the buffer into the "game processor loop, please handle this data" pile, and if it''s a completed write, you dump the buffer into the "available for use" pile.  This is important enough that you want to throw every resource you can at it.  If you are running a multi-processor machine, you run that polling loop with multiple threads to get as much power there as you can.  This is how you keep the server responsive for 10,000 players.  Your game processing loop runs in a different thread altogether (my entire game logic is handled by exactly one thread, and it''s never yet been a bottleneck (though to be fair, it hasn''t yet been stressed much).  I *may* put AI in a different thread, it depends on what I see from the performance numbers once I get it in, heh).Just my $0.02.  I could be wrong, it''s been known to happen ;  RonHiler, i'm not polling individual sockets, i poll them in a bunch... I got several threads, one for low-level networking i/o, and others - for game logic processing... the networking thread does communicate with all clients. So, when receiving poll methods block the thread until there's data to be read (this behaviour is exactly what i want from it - don't eat any CPU time, until there's job to do). But as for sending, the polling methods always return immediately, because there's space available where outcoming data can be put.If wait for read readiness notification for indefinite time, the sending can happen to never be performed at all:while(should_execute){  poll_sockets_for_reading();  read_all_incoming_data();  send_all_incoming_data(); // it can happen that this line (and the previous one) never executes, because poll_sockets_for_reading() waits indefinite time}So, i have to poll for both reading and writing readiness like this:while(should_execute){  poll_sockets_for_reading_and_writing();  read_all_incoming_data();  send_all_outcoming_data();}But... This loop eats 100% CPU, because poll methods return with readiness for writing notification when "data can be sent", and as data almost always can be sent (inner buffers never get fulfilled), the loop starts eating 100% CPU...So i decided to move to another kind of loop:while(should_execute){  poll_sockets_and_return_immediately();  read_all_incoming_data();  write_all_incoming_data();  do_something_to_prevent_this_loop_from_eating_100_CPU();}so, the question is: how do i prevent it from eating 100% CPU?   [edited by - roookie on February 4, 2004 12:38:16 PM]