我试着使用Linxu::2--但在线程中不使用。
如果我在程序中有线程,那么我就会遇到一个崩溃,因为我已经读取了Inotifys。如果我不使用线程,一切都很好。
这里有一个小示例,它应该显示问题。
use strict;
use warnings;
use threads;
use Linux::Inotify2;
my $X = 0; # terminate the thread: 0=nothing, 1=detach, 2=join
STDOUT->autoflush ();
my $ino = new Linux::Inotify2 ();
$ino->blocking (0);
$ino->watch (".", IN_MODIFY | IN_ATTRIB | IN_CREATE) or die "error";
my @ls = (); # for save threads if $X == 2
for (my $i=0;;$i++)
{
my $th = threads->create (sub { print "\nTH". shift; }, $i); # just to have threads; do nothing
if ($X == 1)
{
$th->detach (); # detach the thread
}
elsif ($X == 2)
{
push (@ls, $th); # save for joining after thread finished
}
my @events = $ino->read (); # *** CRASH if $X = 1 or 2
if ($X == 2)
{
foreach (@ls)
{
if ($_->is_joinable ())
{
$_->join ();
}
}
}
sleep (1);
}如果我将$X设置为0,它就会工作。如果将其设置为1或2,则会得到一个运行时错误。
Linux::Inotify2: read error while reading events at /usr/local/lib/x86_64-linux-gnu/perl/5.26.0/Linux/Inotify2.pm line 266.为什么会这样呢?
编辑
我简化了我的样本,以便更好地了解问题。
use strict;
use warnings;
use threads;
use Linux::Inotify2;
STDOUT->autoflush ();
my $ino = new Linux::Inotify2 ();
$ino->blocking (0);
$ino->watch (".", IN_CREATE | IN_DELETE) or die "error";
my $th = threads->create (sub { });
$th->join ();
print "\nINO: ".$ino->poll();删除连接--它会没事,保留它,那么投票就会失败。
发布于 2018-05-09 07:28:06
下面的示例实现了z线人的思想,他建议使用带poll()的事件循环,而不是read()。它是在CentOS 7上用Perl5.16.2和fy2v1.22开发的。
程序生成一个监视/tmp目录的线程。您可以通过触摸和删除文件来测试它:touch /tmp/1 /tmp/2 && rm /tmp/1 /tmp/2
#!/usr/bin/env perl
use warnings FATAL => 'all';
use strict;
use threads;
threads->new(\&_eventListener, '/tmp')->join();
sub _eventListener {
my ($path) = @_;
require Linux::Inotify2;
Linux::Inotify2->import(qw(IN_CREATE IN_DELETE IN_DELETE_SELF));
my $fsEventListener = Linux::Inotify2->new() or
die('Cannot register Linux::Inotify2, stopped');
$fsEventListener->watch(
$path,
IN_CREATE() | IN_DELETE() | IN_DELETE_SELF(),
\&_watchCallback
) or die("Watch creation failed. '$!'");
$fsEventListener->blocking(undef);
while(1) {
$fsEventListener->poll();
sleep 1;
}
return;
}
sub _watchCallback {
my ($e) = @_;
printf STDOUT "Receive event '0x%04x' for file '%s'\n", $e->mask(), $e->fullname();
return;
}https://stackoverflow.com/questions/48589845
复制相似问题