in reply to Re^3: Segmentation fault: problem with perl threads
in thread Segmentation fault: problem with perl threads
When non-detached threads end, they wait until you call join on them before being cleaned up. You do not need to check anything before calling join. If the thread has ended before you call join, it will return immediately. If the thread is still running, it will block until the thread ends. This is how they are designed to work. Your problem lies elsewhere.
Thanks for letting me know the design, where i had falsely assumed something.
You keep posting these snippets of code, but they are so dependant upon the rest of the program that you are not posting, that it is impossible for anyone to run them in order to try and help. They are also full of lumps of commented out code, rambling comments that wrap 3 times and worst of all, all this insane "logger" crap which completely obscures the structure of the code. It is not surprising that you cannot get this to work as you cannot see what it is that you own code is doing.
So, a lot of critisism which you may not like, so I'll try to show you that the critisism can help.
My apologize, for sending unstructured code with unwanted comment which made difficult to people to look at code, who really want to help. Yes i know, the code sent depedends on rest part of the program, but i cannot post the whole code, because it is too big.
Thanks for showing me 'how critisism can help'.
Now the structure and essentials of the code are clear and easy to follow, and it is easy to pick out several problems:
You create your thread here my $th = threads->create( \&worker, $robj );,
but then you do push @thr_arr, $th->tid and then call join() on that object;
which means that @thr_arr contains a list of thread ids, not thread objects!
Correct.
which means when you come to try and join your threads, you are trying to call the method join() on a number and that obviously isn't going to work.
No, you have missed one line, while formatting the code to show how one can neatly post a code which is clear and easy to follow, which actaully gets the thread object associated with thread-id.
sub _replicate{ ... foreach my $k(0..$#thr_arr){ print $k," ",$sc->{rsync}->[$k]->{thr}, $/; if ($sc->{rsync}->[$k]->{thr} eq 'running'){ my $t = $thr_arr[$k]; my $th = threads->object($t); $th->join() if ($th); } } ... }
You are calling rsync using backticks: `$rsync_cmd`;, but you are doing nothing with any ouput produced. That means you are having the system build a pipe and collect the output, and then just throwing it all away.
That is because, im redirecting the command output to a file. If you wish, you can look in sub worker{ ... } and sent datastructure.
Have you heard of system?
Yes. And i consider executing command using backticks(``) is another way of doing it, which in my case does nothing if i use system, right?
And now for the biggest problem, the design of your code in _replicate(). You have 2 nested loops. Within the outer loop you run the inner loop which creates a bunch of threads all trying to contact same server. And then block until that finishes, with several retrys and 120 second waits, before starting another bunch of threads to contact the next server. This is fundamentally bad design. If one server is slow, or broken, with all your threads trying to talk to the same server, you will basically be doing a lot of nothing, when you could be talking to one or more of the other servers in parallel.
Can i ask you, what made you think(from code) that, i contact to different(or next) server when i create next bunch of threads?
For every set of threads i create inside a loop, i contact same server. But during execution (in thread block) i wait, if command execution fails, 120s to contact same server with diff. port.
I appreciate your descriptive post.
katharnakh.
|
|---|