digitalmars.D.learn - Socket server + thread: cpu usage
- Tim (27/27) Apr 29 2014 Hi guys,
- Adam D. Ruppe (6/7) Apr 29 2014 You should be using a blocking socket. With them, the operating
- Tim (13/20) Apr 29 2014 Alright, this would solve the server-cpu-usage-problem. But what
- Tim (6/27) Apr 29 2014 Sorry... I totally forgot... I can use SocketSet's as I already
- Damian Day (4/34) Apr 30 2014 You want to add something like this to your while loop:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/5) Apr 30 2014 Going off topic, the UFCS syntax makes that code much more readable. :)
- Tim (32/39) May 01 2014 Blocking sockets are now working as expected, but I've one
- Tim (4/44) May 01 2014 Small correction: "The CPU usage is low as long as my client is
- Adam D. Ruppe (6/9) May 01 2014 It shouldn't be here, disconnect would affect the new socket, and
- Justin Whear (4/34) Apr 29 2014 If you use blocking sockets, you should probably spawn a new thread for
Hi guys, I've the following snipped: TcpSocket oSocket = new TcpSocket(AddressFamily.INET); oSocket.bind(new InternetAddress("127.0.0.1", 12345)); oSocket.blocking(false); oSocket.listen(0); while(true) { try { Socket oRequestSocket = oSocket.accept(); Request oRequest = new Request(oRequestSocket); oRequest.start(); // Start request thread } catch (SocketAcceptException oException) { Thread.yield(); } } When I execute the code above, the while(true)-loop uses nearly 100% (1 complete cpu). When I connect to the server multiple times (note that each Request-Thread has it's own while(oRequestSocket.isAlive)-loop) the cpu usage easily reaches 120, 130... 200 and more cpu usage. Is there anything I'm doing wrong? I don't want use blocking sockets... how to handle 100 or 1000 connections when the main server thread already consumes 1 cpu?
Apr 29 2014
On Tuesday, 29 April 2014 at 17:16:33 UTC, Tim wrote:Is there anything I'm doing wrong?You should be using a blocking socket. With them, the operating system will put your thread on hold until a new connection comes in. Without them, it will endlessly loop doing absolutely nothing except checking if a new connection is there yet. Horribly, horribly inefficient.
Apr 29 2014
On Tuesday, 29 April 2014 at 17:19:41 UTC, Adam D. Ruppe wrote:On Tuesday, 29 April 2014 at 17:16:33 UTC, Tim wrote:Alright, this would solve the server-cpu-usage-problem. But what about incoming connections? When I create a new thread and use non-blocking socket I've exactly the same problem. I can also solve this problem by using blocking sockets, but what happens if I do the following: while(oMyBlockingSocket.isAlive) { oMyBlockingSocket.receive(...); } ... and close the connection on the client side? I would never receive anything and receive() waits never comes back or would this throw an exception or similar?Is there anything I'm doing wrong?You should be using a blocking socket. With them, the operating system will put your thread on hold until a new connection comes in. Without them, it will endlessly loop doing absolutely nothing except checking if a new connection is there yet. Horribly, horribly inefficient.
Apr 29 2014
On Tuesday, 29 April 2014 at 17:35:08 UTC, Tim wrote:On Tuesday, 29 April 2014 at 17:19:41 UTC, Adam D. Ruppe wrote:Sorry... I totally forgot... I can use SocketSet's as I already asked: http://forum.dlang.org/thread/ogghezngzrvvoqaoddbh forum.dlang.org#post-kivp3e:24jif:241:40digitalmars.com ... but I thought it's also possible using non blocking sockets by using Thread.yield().On Tuesday, 29 April 2014 at 17:16:33 UTC, Tim wrote:Alright, this would solve the server-cpu-usage-problem. But what about incoming connections? When I create a new thread and use non-blocking socket I've exactly the same problem. I can also solve this problem by using blocking sockets, but what happens if I do the following: while(oMyBlockingSocket.isAlive) { oMyBlockingSocket.receive(...); } ... and close the connection on the client side? I would never receive anything and receive() waits never comes back or would this throw an exception or similar?Is there anything I'm doing wrong?You should be using a blocking socket. With them, the operating system will put your thread on hold until a new connection comes in. Without them, it will endlessly loop doing absolutely nothing except checking if a new connection is there yet. Horribly, horribly inefficient.
Apr 29 2014
On Tuesday, 29 April 2014 at 17:44:21 UTC, Tim wrote:On Tuesday, 29 April 2014 at 17:35:08 UTC, Tim wrote:You want to add something like this to your while loop: Thread.sleep( dur!("msecs")( 20 ) ); That will give back some time to the CPU.On Tuesday, 29 April 2014 at 17:19:41 UTC, Adam D. Ruppe wrote:Sorry... I totally forgot... I can use SocketSet's as I already asked: http://forum.dlang.org/thread/ogghezngzrvvoqaoddbh forum.dlang.org#post-kivp3e:24jif:241:40digitalmars.com ... but I thought it's also possible using non blocking sockets by using Thread.yield().On Tuesday, 29 April 2014 at 17:16:33 UTC, Tim wrote:Alright, this would solve the server-cpu-usage-problem. But what about incoming connections? When I create a new thread and use non-blocking socket I've exactly the same problem. I can also solve this problem by using blocking sockets, but what happens if I do the following: while(oMyBlockingSocket.isAlive) { oMyBlockingSocket.receive(...); } ... and close the connection on the client side? I would never receive anything and receive() waits never comes back or would this throw an exception or similar?Is there anything I'm doing wrong?You should be using a blocking socket. With them, the operating system will put your thread on hold until a new connection comes in. Without them, it will endlessly loop doing absolutely nothing except checking if a new connection is there yet. Horribly, horribly inefficient.
Apr 30 2014
On 04/30/2014 04:24 PM, Damian Day wrote:Thread.sleep( dur!("msecs")( 20 ) );Going off topic, the UFCS syntax makes that code much more readable. :) Thread.sleep(20.msecs); Ali
Apr 30 2014
On Tuesday, 29 April 2014 at 17:19:41 UTC, Adam D. Ruppe wrote:On Tuesday, 29 April 2014 at 17:16:33 UTC, Tim wrote:Blocking sockets are now working as expected, but I've one problem. When I do the following in my server-accept-thread: while (m_oSocket.isAlive) { oSocketSet.reset(); oSocketSet.add(m_oSocket); nAcceptedSockets = Socket.select(oSocketSet, null, null, 25.msecs); if (nAcceptedSockets > 0) { // Do something... } } ... and the following in my client: void connect() { m_oSocket = new TcpSocket(AddressFamily.INET); m_oSocket.connect(new InternetAddress("127.0.0.1", 12345)); } The CPU usage is low as long as my connect is connected. When I disconnect the client using the following few lines: void disconnect() { m_oSocket.shutdown(SocketShutdown.BOTH); m_oSocket.close(); } ... the CPU usage goes up. I think that SocketShutdown.BOTH causes Socket.select to fail which results in an endless loop. Any suggestions how to handle that problem? Ali Çehreli: Thanks, didn't know that UFCS can also handle such constructs :)Is there anything I'm doing wrong?You should be using a blocking socket. With them, the operating system will put your thread on hold until a new connection comes in. Without them, it will endlessly loop doing absolutely nothing except checking if a new connection is there yet. Horribly, horribly inefficient.
May 01 2014
On Thursday, 1 May 2014 at 08:08:37 UTC, Tim wrote:On Tuesday, 29 April 2014 at 17:19:41 UTC, Adam D. Ruppe wrote:Small correction: "The CPU usage is low as long as my client is connected. When I disconnect the client using the following few lines:"On Tuesday, 29 April 2014 at 17:16:33 UTC, Tim wrote:Blocking sockets are now working as expected, but I've one problem. When I do the following in my server-accept-thread: while (m_oSocket.isAlive) { oSocketSet.reset(); oSocketSet.add(m_oSocket); nAcceptedSockets = Socket.select(oSocketSet, null, null, 25.msecs); if (nAcceptedSockets > 0) { // Do something... } } ... and the following in my client: void connect() { m_oSocket = new TcpSocket(AddressFamily.INET); m_oSocket.connect(new InternetAddress("127.0.0.1", 12345)); } The CPU usage is low as long as my connect is connected. When I disconnect the client using the following few lines: void disconnect() { m_oSocket.shutdown(SocketShutdown.BOTH); m_oSocket.close(); } ... the CPU usage goes up. I think that SocketShutdown.BOTH causes Socket.select to fail which results in an endless loop. Any suggestions how to handle that problem? Ali Çehreli: Thanks, didn't know that UFCS can also handle such constructs :)Is there anything I'm doing wrong?You should be using a blocking socket. With them, the operating system will put your thread on hold until a new connection comes in. Without them, it will endlessly loop doing absolutely nothing except checking if a new connection is there yet. Horribly, horribly inefficient.
May 01 2014
On Thursday, 1 May 2014 at 08:08:37 UTC, Tim wrote:... the CPU usage goes up. I think that SocketShutdown.BOTH causes Socket.select to fail which results in an endless loop. Any suggestions how to handle that problem?It shouldn't be here, disconnect would affect the new socket, and you're calling select on the accepting socket, which is still good to accept a new connection. What's your code look like for handing a socket returned by accept?
May 01 2014
On Tue, 29 Apr 2014 17:16:32 +0000, Tim wrote:Hi guys, I've the following snipped: TcpSocket oSocket = new TcpSocket(AddressFamily.INET); oSocket.bind(new InternetAddress("127.0.0.1", 12345)); oSocket.blocking(false); oSocket.listen(0); while(true) { try { Socket oRequestSocket = oSocket.accept(); Request oRequest = new Request(oRequestSocket); oRequest.start(); // Start request thread } catch (SocketAcceptException oException) { Thread.yield(); } } When I execute the code above, the while(true)-loop uses nearly 100% (1 complete cpu). When I connect to the server multiple times (note that each Request-Thread has it's own while(oRequestSocket.isAlive)-loop) the cpu usage easily reaches 120, 130... 200 and more cpu usage. Is there anything I'm doing wrong? I don't want use blocking sockets... how to handle 100 or 1000 connections when the main server thread already consumes 1 cpu?If you use blocking sockets, you should probably spawn a new thread for each client. If you use non-blocking sockets, you need to use poll or select to wait for incoming connections or data.
Apr 29 2014