himanshujain_60 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am writing a multi-threaded GUI in perl TK. Beside the main thread, the object of new thread is to monitor a server event queue and when ever there is a new event add it to a scrolled widget. At the same time the main thread might also add data to the scrolled widget as the scrolled widget is used for logging/status window.
When ever I try to add any event to the scrolled object from the child thread, my application dies with the following err:
Attempt to free non-existent shared string '_TK_RESULT_', Perl interpreter: 0x267d22c at C:/Perl/site/lib/Tk/Widget.pm

I would like to know if i can pass the object of scrolled widget or as a matter any hash reference to another thread in perl 5.10?

# Code to create scrolled widget my @CreateOptions = ['ROText', -label=>"Phone $Id", -labelPack => [-side => 'top', -expand + => 0, -anchor => 'w', -fill => 'y'], -wrap => 'none', -relief => 'gr +oove', -width=>$Width, -fg=>'white',-background=>"black", -scrollbars + => 'se']; @PackOptions = [-row=>0, -column=>0, -sticky=>"news", -columnspan=>7, +-rowspan=>19] $AFScroller->{LogScroller} = MW->Scrolled(@CreateOptions);# this is th +e object to scrolled widget $AFScroller->{LogScroller}->grid(@PackOptions); # code where new thread is created and scrolled widget object is used +to add event sub Activate { my $EventQueueTread = Thread->new(\&MonitorEventQueue, ($self, $Id) +); $EventQueueTread->detach; $AFScroller->{'LogScroller'}->insert('end',"xxx yyyyy"); $AFScroller->{'LogScroller'}->see('end'); $AFScroller->{'LogScroller'}->update; # do other stuff return 1; } sub MonitorEventQueue { START: $newevent = Checkeventqueue(); if ($newevent){ $AFScroller->{'LogScroller'}->insert('end',"$newevent");# this is w +hen application dies $AFScroller->{'LogScroller'}->see('end'); $AFScroller->{'LogScroller'}->update; } sleep 1; goto START; }
Your help is very much appreciated
Thanks,
Jai!

Replies are listed 'Best First'.
Re: How to pass scrolled object to another thread
by BrowserUk (Patriarch) on Mar 19, 2011 at 04:43 UTC
    I would like to know if i can pass the object of scrolled widget or as a matter any hash reference to another thread in perl 5.10?

    No. TK isn't thread-safe. Any attempt to call methods on an object handle from thread other than the one in which it was created will fail. Sometimes the failure will be a hard failure--trap or segfault. Sometimes it will be less immediately demonstrative, but it will cause problems. Often of a mysterious and difficult to track nature.

    Rather than have this event thread update the gui directly, the correct way to do this is to pass a message from the event thread to teh gui thread and make all updates to the gui from the gui thread.


    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.
      Hi,

      The Idea is the logging/status window should get update irrespective of any thing, These events happening at server are not triggered by my application and hence the update has to be asynchronous.
      How can I update the GUI then?

      Thanks,
      Jai!
        How can I update the GUI then?

        Here's one way:

        #! perl -slw use strict; use threads; use Thread::Queue; use Tk::Listbox; my $Q = new Thread::Queue; ## start a thread monitoring events async { ## Simulate asynchronous events with random sleeps while( sleep 1+rand 3 ) { ## When an event happens, Q it to the GUI thread. $Q->enqueue( "Event " . time ); } }->detach; my $mw = MainWindow->new; my $lb = $mw->Listbox()->pack; # 10 times per second my $repeat = $mw->repeat( 100 => sub { ##check to see if there are any events in the queue while( $Q->pending ) { ## if there are, grab them my $event = $Q->dequeue; ## adde them to the end of the listbox $lb->insert( 'end', $event ); ## and make sure the latest is visible. $lb->see( 'end' ); } }); $mw->MainLoop;

        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.