expresspotato has asked for the wisdom of the Perl Monks concerning the following question:
Inside a loop eventually crashes the program without any error message. I can see why as defining the thread with my means the next iteration could simply get wiped out, which is probably what happens.foreach (@go_do_something){ my $thr = threads->new(\&some_sub,$_); $thr -> detach(); }
Does not crash the program and seems to be stable after hours of use however it is quickly and consistently leaking memory (more or less 10 MB per iteration). The subroutine some_sub can run for minutes or hours depending on how long the thread takes to run. Any help on how to either: cleanup after the thread is finished (threads->exit() within the tread has no effect on leaking memory), not have my $thr overwrite it self, or your own custom solution would be greatly appreciated. _Kevinforeach (@go_do_something){ $used_threads++; @thr_ll[$used_threads] = threads -> new(\&some_sub,$_); @thr_ll[$used_threads] -> detach(); }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Perl detached threads, loops & my?
by BrowserUk (Patriarch) on Jun 08, 2010 at 23:15 UTC | |
Which OS and versionof Perl are you using? This doesn't seem to leak (with 5.10.1 & Vista):
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.
| [reply] [d/l] |
by expresspotato (Beadle) on Jun 09, 2010 at 00:00 UTC | |
I know the above statement is the WRONG way of using threads but its the only way I know of ensuring a fresh thread each time. It will use all system memory in a matter of seconds. With the following code the program will eventually crash after being run for extended periods (HOURS) of time with other running threads. No error message is observed.
| [reply] [d/l] [select] |
by BrowserUk (Patriarch) on Jun 09, 2010 at 00:19 UTC | |
I'm sorry, but you have an unconstrained flat out loop creating hundreds of thousands of threads ... and you wonder why it runs out of memory? Why are you storing the thread handles when you're detaching them? Did you not see me ask which version of Perl you are using? ... but its the only way I know of ensuring a fresh thread each time. What on earth do you mean by a "fresh thread"? And why are you so certain that you need them? 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.
| [reply] |
by rjt (Curate) on Jun 09, 2010 at 00:27 UTC | |
Thank you for the example. However, I still have doubts. Please carefully consider this reply, my other reply, and BrowserUk's comments. Red flag for me: Your second script, you claim takes "HOURS" to run. On the below mentioned old system, that script completes for me in minutes. Process memory usage never went above 50MB.
You're trying to create 100000 threads. You invite a race condition where your script may hit a wall very quickly if your threads do anything non-trivial. You would expect to see:
Your first example will "leak" memory in the sense that the @thr_ll array will grow to 100000, even after threads exit. On most systems this wouldn't be a big deal if your real application caps at 100000 as well, but I still wouldn't recommend it. I ran both of your scripts on my oldest machine, and neither one had a deleterious effect on Perl 5.10.1 on Ubuntu, running on an 8 year old P4-1.6GHz machine with 512MB. Both ran to completion. | [reply] [d/l] [select] |
by llancet (Friar) on Jun 09, 2010 at 01:13 UTC | |
with a somehow new version perl and threads: Actually, if I do something like your second example, it would core dump immediately:
| [reply] [d/l] [select] |
|
Re: Perl detached threads, loops & my?
by rjt (Curate) on Jun 08, 2010 at 23:59 UTC | |
We need more information. What does @go_do_something contain? How many threads are you trying to create? What are they doing? In other words, can you give us a runnable but minimal example that exhibits the behavior on your system? Memory leak? Maybe, but, again, a real example would be necessary, here, plus some information on how you're measuring the memory and determining there is a leak. You said it "crashes the program without any error message". Is it possible that your script just decided it was done creating threads and exited on its own? That would produce behavior consistent with what you are seeing. Since you've detached every thread, once your @go_do_something loop exits, how do you know (in your code) that all of your threads have finished and it is safe to exit your program? What was its exit status when execution was complete? I might be completely missing the issue, here, but with the limited information available, this really seems most likely to me. Maybe you have a valid reason for detaching everything, but if you want to be sure all threads have finished, you might consider something along the lines of:
| [reply] [d/l] |
by expresspotato (Beadle) on Jun 09, 2010 at 01:56 UTC | |
The only reason I "store them" is to ensure it is a fresh thread everytime. Using my $thr -> will eventually crash. The script is designed to do one thing. Process the list of tasks and just keep on going. Tasks (detached threads) may take a second and they may take an hour. I do not claim it takes "Hours to run", I claim it may be "run for hours". @llancet Ah ha! See... Always calling my $thr on occasion seems to overwrite / invalidate the older thread. When checking memory usage using my $thr, it never seems to increase which is very odd to me. @rjt Thanks for the code, however the script is "always running" and does not ever exit. Perhaps the actual code will shed some light on what is really going on. Its attached below. Keep in mind the same problem still exists. How to ensure this is a FRESH thread (as my or the same $thr will eventually crash), without wasting all that memory.
| [reply] [d/l] |
by BrowserUk (Patriarch) on Jun 09, 2010 at 02:23 UTC | |
@expresspotato. This ain't twitter. What you are doing makes no sense. What you say you need: "FRESH threads" makes no sense. And if you cannot be bothered to answer my questions properly, then I can't be bothered to help. Good luck. | [reply] |
by rjt (Curate) on Jun 09, 2010 at 03:08 UTC | |
This is obviously neither the real code nor an example that we can run. Please, help us help you. Read the responses you've been given, and give us a minimal and runnable! example (with inputs and expected outputs) with strict and warnings that we can use to reproduce the undesired behavior that you see. Until then, we can't effectively help you. | [reply] |