我有一個有GTK2 GUI的Perl程序(通過Gtk2
包)。該程序還會在另一個線程中打開網絡套接字(實際上通過LWP
),並不斷請求某個URL,等待事件發生。如何在Perl GTK程序中獲得跨線程通信?
如果發生事件,則必須處理和解釋其數據,並使用適當的回調函數來更新GUI。這是我的程序崩潰的地方。
主程序:
# Attach to the "message received" event
Foo::hook('msgRx', \&updateMsg);
# ...
Gtk2->main();
sub updateMsg {
my ($msg) = @_;
print "New message: $msg\n";
# append to a GTK TextView -- code is also used elsewhere and works fine
appendMsg($msg);
}
和模塊中:
# ...
my %hooks =();
my $ev_pid = undef;
sub hook($&) {
my ($name, $sub) = @_;
$hooks{$name} = $sub;
}
sub call_hook {
my ($name, @args) = @_;
print ">>> CALLING HOOK $name\n";
return $hooks{$name}->(@args) if (defined($hooks{$name}));
}
sub eventThread {
while (1) {
my $res = $browser->post("$baseurl/events", ['id' => $convid]);
my $content = $res->content;
last if ($content eq 'null');
my $events = from_json($content);
foreach (@$events) {
my $ev_type = shift @$_;
my @ev_args = @$_;
print "Event type: $ev_type\n";
print Data::Dumper->Dump([@ev_args]);
handleEvent($ev_type, @ev_args);
}
}
}
sub doConnect() {
# ...
$ev_pid = fork;
if (!defined $ev_pid) {
print "ERROR forking\n";
disconnect();
return;
}
if (!$ev_pid) {
eventThread;
exit;
}
}
現在從這些輸出的控制檯是我所期望的:
>> Starting... [["connected"]] Event type: connected >>> CALLING HOOK start [["waiting"]] Event type: waiting >>> CALLING HOOK waiting [["gotMessage", "77564"]] Event type: gotMessage $VAR1 = '77564'; >>> CALLING HOOK msgRx New message: 77564 [["idle"]] Event type: idle >>> CALLING HOOK typing [["gotMessage", "816523"]] Event type: gotMessage $VAR1 = '816523'; >>> CALLING HOOK msgRx New message: 816523 >> User ending connection null >>> CALLING HOOK end
然而,GUI TextView的不不更新。我只能假設這是因爲回調實際上發生在另一個線程中,其中有對象的重複。
有什麼建議嗎?
我知道可能是這種情況。可悲的是我不能依賴`線程'可用。感謝雖然:-) – DMI 2009-06-12 14:13:18
作爲trendels建議,您可以使用IPC來解決您的進程通信問題。 – Igor 2009-06-12 14:34:09