【发布时间】:2009-06-12 13:47:31
【问题描述】:
我有一个带有 GTK2 GUI 的 Perl 程序(通过 Gtk2 包)。该程序还在另一个线程中打开了一个网络套接字(实际上是通过LWP),不断地请求某个URL,等待事件发生。
如果发生事件,则必须处理和解释其数据,并使用适当的回调函数来更新 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;
}
}
现在这些控制台输出是我所期望的:
>> 开始... [[“连接的”]] 事件类型:已连接 >>> CALLING HOOK 开始 [[“等待”]] 事件类型:等待 >>> 呼叫挂钩等待 [["gotMessage", "77564"]] 事件类型:getMessage $VAR1 = '77564'; >>> 呼叫挂钩 msgRx 新消息:77564 [[“闲”]] 事件类型:空闲 >>> CALLING HOOK 打字 [["gotMessage", "816523"]] 事件类型:getMessage $VAR1 = '816523'; >>> 呼叫挂钩 msgRx 新消息:816523 >> 用户端连接 空值 >>> CALLING HOOK 结束
但是,GUI TextView 不会更新。我只能假设这是因为回调实际上是在另一个线程中发生的,该线程具有重复的对象。
有什么建议吗?
【问题讨论】:
标签: perl multithreading gtk ipc