1

A little background:

I'm working on a Windows program that uses RPC to communicate over a network. Network connections are made and disconnected continuously. The RPC calls are synchronous, but there are more than one client threads operating simultaneously. The programs are symmetric - that is to say, both sides act as client and server, and are running the exact same software. It's implemented in C++ using the standard Windows API.

The problem:

The number of thread handles reported by Process Explorer increases over time. It appears that threads are made by the RPC runtime to handle the requests, but that the handles are not always cleaned up when the thread is reclaimed.

The number increases especially when there is a lot of data being transmitted, or when there are many calls happening simultaneously (these two factors come hand-in-hand, and I am unsure which is relevant).

An active server can build up several thousand unused thread handles over the course of a few days, while never using more than 20 threads at any time.

The question:

What can I do to keep the handle count from mounting, because I believe it may be causing stability issues at customer sites?

TheWalruss
  • 33
  • 3
  • [Writing Windows NT Server Applications in MFC Using I/O Completion Ports](http://msdn.microsoft.com/en-us/library/ms810436.aspx) – Serg Jan 22 '13 at 13:48

1 Answers1

0

Well, something that is surprising is that even when a thread terminates, this doesn't free all of its resources. You have to call CloseHandle() on the thread handle you received from beginthreadex or what the thing was called. Also, don't (!!!) use CreateThread(), see the MSDN docs.

There is one other thing, though that doesn't cause your problems, and that is the perpetual starting and terminating of threads. Instead, use a thread pool. Also, but this depends on your actual setup, you only need a single thread per network interface for IO and a single thread per CPU for computations. Using a thread pool, you can easily limit this number. Keeping these under control should limit the overhead caused by thread creation/cleanup and context switching. This isn't always feasible if a connection switches a lot between network IO, CPU and possibly disk IO or even UI.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
  • The problem is that I'm not the one opening these threads - that's all handled behind the scenes by the RPC runtime. However, I can try calling CloseHandle() before the remote function closes, and see what happens. It's worth a try - thanks for the idea! – TheWalruss Jan 23 '13 at 07:09
  • No, it is not seem possible for a thread to close existing handles to itself - the alternative is to duplicate a handle and close that, but, as expected, that accomplishes exactly nothing. The RPC runtime does appear to use a thread pool, because I often see threads being "reused" for different calls. I am now going to experiment by calling AfxEndThread() instead of returning from remote calls - perhaps that cleans things up better. – TheWalruss Jan 23 '13 at 08:21
  • That's bad, if the RPC system is not reusing threads but also not ending them, that's a bug there. The only thing that could cause it in your code is if you manage to never return or if you manage to confuse the RPC system somehow, by e.g. exiting your callback by throwing an exception. Try to reduce the things you do in your code to see if it goes away. – Ulrich Eckhardt Jan 25 '13 at 20:16