Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Re: Re: Re: Re: Re: returning from a thread ?

by Foggy Bottoms (Monk)
on Aug 22, 2003 at 13:46 UTC ( [id://285777]=note: print w/replies, xml ) Need Help??


in reply to Re: Re: Re: Re: Re: returning from a thread ?
in thread returning from a thread ?

Hi Liz,

It's me again... and back to square one - I fixed all my Perl 5.8 migration problems and am back on the thread problem. I've just tested it and it still doesn't return.

What is the exact bit of code that tells the thread not to freeze the parent process ? If it is detach(), then if it comes after having created and started the thread, how can it possibly know ?

This may be a dumb question, sorry for the inconvenience...
  • Comment on Re: Re: Re: Re: Re: Re: returning from a thread ?

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Re: Re: returning from a thread ?
by liz (Monsignor) on Aug 22, 2003 at 14:04 UTC
    After starting a thread, execution of the parent process simply continues. An example:
    use threads; use threads::shared; my $run : shared = 1; my $thread = threads->new( sub { while ($run) { print "Hi!\n"; sleep 1; } } ); print "Waiting 5 seconds while the thread runs\n"; sleep 5; print "Shutting down\n"; $run = 0; $thread->join;
    This should display (possibly in a different order:
    Hi!
    Waiting 5 seconds while the thread runs
    Hi!
    Hi!
    Hi!
    Hi!
    Shutting down
    
    If it doesn't, there is a problem with threads in your environment.

    Liz

      Here goes...
      • To start with, the code that creates and calls the thread - this code is in a file called gui-new.pl
        sub B_resetScan_Click # saves text file, stops thread, restarts thread +. { # open file for write - we want to overwrite the previous file with + the new one open(FOLDERLIST, ">".LTG::dialog::CONFIGFILE) or die "Can't create/ +overwrite file: $!\n"; print FOLDERLIST "#FORCE#\n"; # category ID foreach (0..$window->LB_forceFolder->Count()) { # add each element of the force folder after replacing backslash +es by forward slashes my $folder = $window->LB_forceFolder->GetString($_); while ($folder =~ /\\/){ $folder =~ s/\\/\//; } print FOLDERLIST $folder."\n"; } print FOLDERLIST "#BAN#\n"; # category ID foreach (0..$window->LB_banFolder->Count()) { # add each element of the ban folder my $folder = $window->LB_banFolder->GetString($_); while ($folder =~ /\\/){ $folder =~ s/\\/\//; } print FOLDERLIST $folder."\n"; } close (FOLDERLIST); # now stop the current scan thread # to do this, write in a file th_com.thd the value 0 #if (defined $thread) #{ # open (THREADCOM, ">".LTG::dialog::THREADCOM) or die "Can't crea +te/overwrite file: $!\n"; # print (THREADCOM,"0"); # close THREADCOM; # stop thread #} print "create thread\n"; my $run : shared = 1; $thread = threads->new(\&LTG::scanChange::monitor());# \&LTG::scanC +hange::monitor); print "Waiting 5 seconds while the thread runs\n"; sleep 5; print "Shutting down\n"; $run = 0; $thread->join; }

        For the sake of the code, I copied yours in mine and made the adequate changes (ie function name) but I still kept the sleep and the join which I won't need later...
      • And here's the code of the function called via the thread LTG::scanChange::monitor()
        sub monitor { my @wantedF; # folders to be scanned my @bannedF; # banned folders not to be scanned if ( -e LTG::dialog::CONFIGFILE) { open(FOLDERLIST,LTG::dialog::CONFIGFILE) or die "can't open file +"; my $content = <FOLDERLIST>; my $addForce = 0; while ($content) { if ($content ne "\n") { $content =~ s/\n/ /; ($content =~/^\#FORCE\#/)?($addForce = 1):(($content =~/^\# +BAN\#/)?($addForce = 0):($addForce?push(@wantedF,$content):push(@bann +edF,$content))); } $content = <FOLDERLIST>; } close (FOLDERLIST); } #open (THREADCOM, ">".LTG::dialog::THREADCOM) or die "Can't create/ +overwrite file: $!\n"; #print THREADCOM "1"; #close THREADCOM; #my $active = 1; my $run : shared; while ($run) { # if ( -e LTG::dialog::THREADCOM) # { # open(THREADCOM,LTG::dialog::THREADCOM) or die "can't open fi +le THREADCOM"; # $active = <THREADCOM>; # print "active : $active \n"; # close THREADCOM; # } my %changes = LTG::scanChange::startScan(\@wantedF,\@bannedF,INC +_SUBDIRS); foreach my $k (keys %changes) { print "key : $k -> content : $changes{$k}\n"; } # update database here Sumith print "---while---\n"; } }
      I suspect the error comes from the fact that the shared variable should be global to gui-new.pl instead of local to the function creating the thread...
      Please note that the function monitor freezes as long as there's no change on the hard drive... Should there be one, it notifies the user and loops in the while again...

        There are a couple of pretty significant problems with your code.

        ... print "create thread\n"; my $run : shared = 1; $thread = threads->new( \&LTG::scanChange::monitor()); # \&LTG::scanChange::monitor); print "Waiting 5 seconds while the thread runs\n"; sleep 5; print "Shutting down\n"; $run = 0; $thread->join; }

        First, this line

        $thread = threads->new(\&LTG::scanChange::monitor());

        By adding the parens to the end of the sub name, you are completely changing the meaning of this line. vis:

        sub test{ print 'Hello world' } print \&test; CODE(0x1bc2cdc) print \&test() Hello world SCALAR(0x1bc2d18)

        In the first case, without the parens, the \&subname returns a code reference to (the address of) subname. This is required so that threads->new() knows what code to run in the new thread.

        In the second case, with the parens, the \&subname(), invokes the sub, in the context of the current thread--hence you see the "Hello World" printed.

        Then a reference is taken to the return value of the sub--which is the '1' from the print statement in this case--hence a scalar reference gets output.

        Passing a scalar reference to threads->new( \1 ); ought to be giving you an error message, regardless of whether your using warnings or strict.

        thread failed to start: Not a CODE reference at ...

        Are you not seeing this?

        I note that you have the correct format of the call in a comment on the end of that same line?

        The second, and perhaps more fundemental error is way you are using the thread overall. Essentially, what you are doing is

        # Do some stuff $thread->new( ...); # start a thread sleep ...; # Sleep a while $thread->join; # Wait for the thread to finish. # do some other stuff.

        What this means is that there is completely no reason for using a thread at all here. You are blocking your main thread whilst the second thread runs to completion.

        You would achieve exactly the same result by simply calling the sub at this point and avoiding all the sharing stuff.

        I'd try and offer further suggestions on how to make your code do what you want, but to be frank, it's not at all clear to me what it is that your are trying to achieve. The code you have posted is such a small window in the over all scheme of your module that it makes it difficult to see what is going on. Perhaps you could post a (brief) pseudo-code or textual description of the overall program, and explain what you are hoping to achieve by using threads. Then we might be able to suggest a workable strategy.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
        If I understand your problem, I can solve it! Of course, the same can be said for you.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2024-04-18 19:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found