in reply to using many threads and conserving stack size

Add $thr->detach; after the create.

On my system I reach a steady state memory usage of around 2.7 MB after a few seconds.

That's with threads v1.71. (YMMV with earlier versions).


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: using many threads and conserving stack size
by danmcb (Monk) on Nov 12, 2008 at 14:33 UTC

    ah, there is a gotcha. If I detach every thread, then the script exits before all threads have actually exited. What I want is to get back the memory of the threads when they exit, but I want every thread to complete its sleep and then exit. That is really important for this application.

      Sorry. I shouldn't post just before leaving. You're right. There is still no architected way to find out how many detached threads are still running. So, you need to implement some counting mechanism yourself.

      A simple shared scalar that you increment when the threads start and decrment when the threads end is simple and efficient.

      #!/usr/bin/perl -w use strict; use threads; use threads::shared; my $running :shared = 0; for (my $i = 0; $i < 50; $i++){ my $thr = threads->create( \&_run_thread, $i ); $thr->detach; sleep 1; } sleep 1 while $running; print "ok.\n"; sub _run_thread { { lock $running; ++$running; } my ($id) = @_; print "starting thread $id ...\n"; sleep 4; print "exiting thread $id.\n"; { lock $running; --$running; } return; }

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      What that comes down to getting the parent to know when a thread has finished.

      You could use Thread::Queue, and each thread can enqueue its id when it's finished. The parent could wait on that queue or poll it.

      Or you could poll threads->list(threads::joinable) for threads you can polish off by joining. You might do that before creating a new thread, I suppose.

        thanks. seems a bit odd, I don't see why it has to work like this. It ought to be trivial to run the script until all threads are ended, without clogging memory

        In the end I just made a threadless version with a very simple scheduler, it took me about an hour to change it and it works perfectly on almost 0 resources

Re^2: using many threads and conserving stack size
by danmcb (Monk) on Nov 12, 2008 at 13:58 UTC
    thanks, that's all that was needed^H^H^H ... no it wasn't because it breaks the next part of the code that waits for all threads to finish before exiting - see below.