How to avoid running out of OS thread handles when spawning lots of short-lived threads?

Steven Schveighoffer schveiguy at yahoo.com
Thu Jun 9 17:42:47 PDT 2011


On Thu, 09 Jun 2011 19:57:27 -0400, David Nadlinger <see at klickverbot.at>  
wrote:

> On 6/10/11 1:37 AM, Steven Schveighoffer wrote:
>> t.join() ?
>>
>> http://www.digitalmars.com/d/2.0/phobos/core_thread.html#join
> Doesn't work, in my application I'm a) using std.concurrency, and b)  
> even that is hidden behind the API I want to test. A better example  
> would probably be the following, which crashes before reaching 600  
> iterations on my Arch Linux VM:

In my previous application (admittedly, this was D1 and Tango, but  
essentially the same Thread class), I've run and terminated thousands and  
thousands of threads from a single process execution, and never had that  
problem.

Now, std.concurrency, I'm not too familiar with.  So I'm of little help  
there...

> ---
> import std.concurrency;
>
> void doNothing() {}
> void main() {
>    foreach (i; 0 .. 1_000_000) {
>      spawnLinked(&doNothing);
>      receive((LinkTerminated t){});
>    }
> }
> ---
>
> I realize that spawn()ing lots of threads without causing much GC  
> activity may be an edge case that probably only occurs during testing,  
> but I'd still be interested in a workaround. (GC.collect() to collect  
> the remaining Thread objects and thus cause the threads to be detach()ed  
> unfortunately breaks on OS X:  
> http://d.puremagic.com/issues/show_bug.cgi?id=6135).

I would be uneasy if thread joining or cleanup depends on the GC.  Indeed,  
I don't see anything in std.concurrency that joins threads which  
terminate.  That may be the issue.  Receiving a termination message  
probably should join the thread...

What I'd suggest is this: modify std.concurrency to put the thread inside  
the Tid struct (currently, it's not stored anywhere), then call join on  
that thread when you are sure it's dead.  So your code will look like this:

auto tid = spawnLinked(&doNothing);
receive((LinkTerminated t) {});
tid.theThread.join();

See if that helps.  If it does, file a bug against std.concurrency.

>> AFAIK, a thread cannot go away until you join it, because it still has
>> to give you its exit status.
> Not if you call pthread_detach(), after which calls to pthread_join()  
> are defined to be invalid.

Are you calling that?  The only place that calls that in druntime I can  
find is the Thread dtor.

-Steve


More information about the Digitalmars-d-learn mailing list