Jump to content
  • Advertisement
Sign in to follow this  
cv0746

blocking multithreaded vs nonblocking single threaded socket application

This topic is 3883 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Advertisement
Either. CPUs are hundreds of times faster than the actual network, so there's very little, if any difference. From a CPU usage point of view, blocking sockets are better, since they allow the OS to block a thread, rather than having it screaming along using up 100% of the CPU to keep polling a socket.

Share this post


Link to post
Share on other sites
Just be careful to use the right tool for the right job. People tend to fix problems by throwing multi-threading at them when doing so often just makes things awful to debug. In terms of blocking threads, consider the following scenario.

1) Server transmits a datagram

2) Client blocks until it determines a buffer has been filled, signalling the arrival of Server's datagram.

Clearly, things are going to go pear-shaped if there is some consumer on the client waiting for the the blocking read to complete. Asynchronous reads are a really good idea if you can afford the pain of implementing them (note: many networking libraries already do this for you...) -- but can be overkill if you can guarantee that it doesn't matter when your application blocks.

Either way, good luck with whatever you're up to ;)

~Shiny

p.s. As steve said -- your latency is a factor of network load and NIC performance (to name just two things) -- unless you're transmitting outside your building and across sub-nets, expect local latency to be < 1 ms.

Share this post


Link to post
Share on other sites
Consistent RTT can only be achieved through the use of unreliable UDP protocol (limiting ourselves to commodity transports), and by designing your logic in such a way that it tolerates moderate packet loss/delays/unordered events.

How you send them then doesn't matter, you'll need to choose something that will meet the above criteria.

And, given that UDP is implied, there's really no practical use for blocking threads, since that only requires you to synchronize two threads, when single thread would work just fine.


Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
Either. CPUs are hundreds of times faster than the actual network, so there's very little, if any difference. From a CPU usage point of view, blocking sockets are better, since they allow the OS to block a thread, rather than having it screaming along using up 100% of the CPU to keep polling a socket.



IMO it's perfectly practicable to use non-blocking sockets with select() without using up 100% of the CPU (select() is not really polling the sockets per sé).

Share this post


Link to post
Share on other sites
It should also be noted that running a single socket per thread is generally a huge waste of resources.

On the server end, designing for IOCP usage isn't overly difficult (assuming you know what you're doing), and non-blocking sockets on the client side are just fine.

Share this post


Link to post
Share on other sites
Quote:
IMO it's perfectly practicable to use non-blocking sockets with select() without using up 100% of the CPU (select() is not really polling the sockets per sé).


It is typically not particularly useful to run non-blocking sockets with select(), at least when you have a small number of sockets. If select() returns a socket as readable or writable, you are guaranteed that a call to send() or recv() on that socket will not block, no matter whether the socket is blocking or not. And if you set a socket to non-blocking, you can just call recv() or send() without worrying about blocking, so you don't need to call select(). For lots of sockets with sporadic traffic, calling select() and then only doing I/O on "ready" sockets is more efficient. For lots of sockets with constant traffic, it might be more efficient to just do I/O on each of the sockets in non-blocking mode, and forgo select() entirely.

Share this post


Link to post
Share on other sites
Quote:
If select() returns a socket as readable or writable, you are guaranteed that a call to send() or recv() on that socket will not block, no matter whether the socket is blocking or not.


Thats wrong! You are only guaranteed to send 1 byte without blocking.

From the select documentation:

Quote:
If the socket is not processing a connect call, writability means a send, sendto, or WSASendto are guaranteed to succeed. However, they can block on a blocking socket if the len parameter exceeds the amount of outgoing system buffer space available.


[Edited by - imgty on January 18, 2008 3:51:34 AM]

Share this post


Link to post
Share on other sites
Erm .. I'm not being funny, but where in that quote does it mention that the buffer size is 1 byte?

You can set the send / receive buffer sizes using setsockopt with either SO_SNDBUF or SO_RECVBUF, which should be enough to work around this issue.

You should use UDP in which case it's pointless using more than one socket anyway, thus relieving you from your problem.

If you are sure TCP is the right choice (even though it is wrong for this kind of application) then suggest you peek at the Apache sources for speed tips seeing as it's one of the fastest web servers. FYI it uses threading.

PS. Learn / use UDP.

Share this post


Link to post
Share on other sites
Quote:
Thats wrong! You are only guaranteed to send 1 byte without blocking.


No, it's right. The next call to send() will not block. However, send() does not guarantee to send the entire buffer you request, at least not on stream sockets. That's why it returns the number of bytes sent. For datagram sockets, you are guaranteed to be able to send at least one datagram, although the size of that datagram is unspecified. (I know of no implementation that makes that limit less than one MTU, though)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!