Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: ithreads memory leak

by sundialsvc4 (Abbot)
on Apr 08, 2015 at 23:37 UTC ( #1122864=note: print w/replies, xml ) Need Help??


in reply to ithreads memory leak

Truer words have never been spoken than what BrowserUK just so-well said:   the key is to limit the number of threads that are active at any one time, and to separate this from the number of requests amount of work that they have to do.   Even if you receive (say ...) 1,000 start messages in the space of (say ...) one millisecond, you must not attempt to “therefore ...” launch 1,000 threads.   Instead, some of those requests will briefly have to wait-their-turn.

You should have a pool of “worker threads,” of some configurable size that will not exceed this system’s capacity.   All of those threads, however many there may be, should be waiting for a message (start ...) to arrive on a common, thread-safe queue.     Meanwhile, your main thread, instead of “starting a new thread” each time such a message arrives, should instead be posting the message to that queue.   When such a message arrives for them, they carry out the work, then wait again.   (The main-thread is the only “writer.”   All of the workers are “readers.”)   If any worker is waiting, it will get the message without delay.   If all of the workers are busy, the message will briefly sit in the queue until some worker can receive it.   Nevertheless, the total number of threads that the operating system is being asked to support ... or, to provide memory for ... will never grow beyond the proscribed limits, no matter how stuffed-up the queue (momentarily) gets.

And, there’s already a lot of CPAN code out there to help you, so be sure not to re-invent the wheel here.   (Say ...) Thread::Pool, Thread::Queue, Thread::Signal . . .

You should, of course, design the threads so that they dispose of all storage needed to service their latest request, before they go-to-sleep waiting for another request to arrive.   If you take care to do that, Perl’s very-clever memory manager should automagically take care of the rest.   Yes, the memory-size of the parent process may grow to be large, but it should not grow uncontrollably leak.

Replies are listed 'Best First'.
Re^2: ithreads memory leak
by DNAb (Novice) on Apr 09, 2015 at 16:27 UTC

    I see what you are both saying, I'm just not 100% sure how to make this code any different right now. It's somewhat unique, but it's still totally in beta so I'm fine with revisiting most aspects.

    The use case is as follows: An assortment of showcases are alarmed. To access a showercase a user must press a function key on a keypad, this starts a timer which gives them up to three minutes to open the showcase. If the user doesn't open the showcase, update the database to require another key press, if the user does open the showcase update the point as open in the database and then kill the walking timer, and start the open timer. The open timer lets them keep the door open for ten minutes, if this timer expires then send an alert, otherwise when the user closes the door kill the open timer. I realize this is complicated, I'm trying to give anyone reading this thread an idea of why it is how it is.

    Anyway, as promised here is the code:

    (Fair warning, by anyone's standards it's probably ugly)

      First:Ignore anything and everything sundialsvc4 says. He has a proven track record of meaningless, misdirected & pure malicious posts on subjects he has provably no knowledge or understanding of. And in particular, threads.

      then kill the walking timer,

      The fundamental problem with your code is this:

      #! perl -slw use strict; use threads; sub sleeper { print "thread started; sleeping"; $SIG{'KILL'} = sub { print "Thread dieing"; threads->exit(); }; sleep( 1000 ); print "Thread dieing"; threads->detach; } my $t = threads->new( \&sleeper ); sleep 5; print "Killing thread"; $t->kill( 'KILL' )->detach; print "thread status: ", $t->error(); sleep 100 while 1;

      Run that code and watch the process (top or whatever). It immediately creates a thread that just sleeps for a thousand seconds. The main thread then waits for 5 seconds and then (attempts to) kills the sleeping thread. But the thread never sees the "signal" ... until it finishes sleeping.

      This is because those "signals" aren't real signals; but some home-brewed simulation of them that cannot even interrupt a sleep. They (the pseudo-signals), should never have been added to the threads api; and they should never be used!

      And that explains the "memory growth" problem; you are expecting these threads to go away when before you start their replacements; but they simply won't.

      And that's a problem for your architecture which is built around that premise.

      I have 3 solutions for you: one is a quick fix; and the other two will required fairly extensive changes to your program.

      (But its my dinner time right now, so I'll detail them in a while. I just wanted to warn you to ignore sundialsvc4 who has never posted a single line of working code here. Be warned!)


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      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". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

        Ah I see this caveat noted in the thread docs now, thank you for clearing this up.

        I'm happy to listen to any suggestions you can offer (when you have free time of course!), and I'm willing to put work into this, assuming it's near my level of competence.

        Again, thanks!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1122864]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2019-11-17 03:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Strict and warnings: which comes first?



    Results (85 votes). Check out past polls.

    Notices?