我正在寻找一种在Perl中实现读/写锁的好方法.这需要在Windows和Unix上同步来自不同Perl线程和/或进程的文件访问.尝试过Fcntl :: flock,如果按预期工作,对我来说是完美的.不幸的是,看起来在压力下flock允许在另一个线程中锁定已经锁定的文件.查看了一些CPAN模块,但大多数都是用flock实现的.接下来我打算评估Unix的win和Win32 :: Mutex的fcntl.这似乎是一项非常常见的任务,也许我错过了一些简单的解决方案.如果您知道任何问题,请指点一下吗?
谢谢!
下面列出的程序失败,并出现以下错误:
JSON text must be an object or array (but found number, string, true, false or null, use allow_nonref to allow this) at json_test.pl line 10.
Run Code Online (Sandbox Code Playgroud)
当我注释掉线程启动/连接,或者在运行线程之前解析JSON时,效果很好。消息似乎来自JSON库,因此我想这有问题。任何想法怎么回事以及如何解决?
# json_test.pl
use strict;
use warnings;
use threads;
use JSON;
use Data::Dumper;
my $t = threads->new(\&DoSomething);
my $str = '{"category":"dummy"}';
my $json = JSON->new();
my $data = $json->decode($str);
print Dumper($data);
$t->join();
sub DoSomething
{
sleep 10;
return 1;
}
Run Code Online (Sandbox Code Playgroud) 我需要创建一个将由其他开发人员使用的包.实现静态方法的最佳方法是什么?对于静态(类)方法,我必须期望第一个参数$ class,并且必须将方法作为类方法调用:
My::Package->Sub1();
Run Code Online (Sandbox Code Playgroud)
从另一方面,我可以写一个"常规"包子程序(没有预期的$ class参数),它将完美地做同样的事情,但需要以不同的方式调用
My::Package::Sub1();
Run Code Online (Sandbox Code Playgroud)
因此,基本上与业务功能的角度没有区别(至少我没有看到它,除了通过第一个参数的包名称可用性),但实现和调用有两种不同的方式.有点令人困惑.我应该使用哪种方式?何时使用?有一些规则吗?另外,我应该检查方法是否按预期调用(静态vs包)?
下面的代码按照我在 Unix 上的预期工作 - system() 调用会阻塞,直到子进程完成。在 Windows 上,尽管它的工作方式不同 - system() 仅阻塞,直到子脚本到达 exec(),然后它立即返回,并且 exec-ed 子脚本继续在后台运行。有没有办法让它像在 Unix 上一样工作?
# main script
my $myCmd = [$^X, 'myScript.pl', 'arg1', 'arg2'];
system($^X, 'runcmd.pl', @$myCmd);
# runcmd.pl
open(STDOUT, '>', 'out.tmp');
open(STDERR, '>', 'err.tmp');
my $exe = shift @ARGV;
unless(exec($exe, @ARGV))
{
close(STDOUT);
close(STDERR);
exit(1);
}
# myScript.pl - any script that runs few seconds and produces some output, e.g:
foreach (1..5)
{
sleep 1;
print "$_\n";
}
Run Code Online (Sandbox Code Playgroud) 下面的代码假定运行2个并行线程,每个线程执行fork(),等待子进程完成,然后线程应加入(完成)并打印结果。实际上,第一个分叉的子进程按预期完成,但是第二个分叉挂在_mutex_lock()上试图退出,因此第二个线程永远不会加入,直到您用-9信号手动杀死第二个子进程为止。有人可以解释为什么会发生这种情况,以及如何避免这种情况吗?
use strict;
use warnings;
use threads;
use Data::Dumper;
sub Run
{
my $tid = threads->tid();
my $log = {};
$log->{"[$$:$tid]:00"} = "started";
my $pid = fork();
if ($pid == 0)
{
print "In child ($$): started\n";
sleep 3;
print "In child ($$): finished\n";
# system("kill -9 $$"); -- brutal way
exit 0;
}
waitpid($pid, 0);
my $exitCode = $? >> 8;
$log->{"[$$:$tid]:01"} = "finished, code=$exitCode";
return $log;
}
my @threads = ();
foreach (1..2)
{
push @threads, threads->new(sub { …Run Code Online (Sandbox Code Playgroud)