Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Perl中的读写锁_Multithreading_Perl - Fatal编程技术网

Multithreading Perl中的读写锁

Multithreading Perl中的读写锁,multithreading,perl,Multithreading,Perl,我正在寻找一种在Perl中实现读/写锁的好方法。 这是在Windows和Unix上同步来自不同Perl线程和/或进程的文件访问所必需的。 尝试了Fcntl::flock,如果它按预期工作,它将非常适合我。不幸的是,在压力下,flock允许在另一个线程中对已经锁定的文件设置锁定。 研究了一些CPAN模块,但大多数是用flock实现的。 接下来,我计划评估用于Unix的fcntl和用于Windows的Win32::Mutex。 这似乎是一项非常常见的任务,也许我缺少了一些简单的解决方案。 如果你知道

我正在寻找一种在Perl中实现读/写锁的好方法。 这是在Windows和Unix上同步来自不同Perl线程和/或进程的文件访问所必需的。 尝试了Fcntl::flock,如果它按预期工作,它将非常适合我。不幸的是,在压力下,flock允许在另一个线程中对已经锁定的文件设置锁定。 研究了一些CPAN模块,但大多数是用flock实现的。 接下来,我计划评估用于Unix的fcntl和用于Windows的Win32::Mutex。 这似乎是一项非常常见的任务,也许我缺少了一些简单的解决方案。 如果你知道有什么,你能帮我指出吗


谢谢大家!

群集不会跨线程执行您想要的操作

您可以使用实现自己的锁定,如果与
O|u EXCL | O_create
一起使用时文件存在,则锁定将失败

例如,子进程竞争锁

use warnings;
use strict;
use feature 'say';
use Fcntl;
use Time::HiRes qw(sleep);

my $lock_file = ".lock.$$";
sub get_lock {
    my ($file, $pid) = @_; 
    my $fh;
    while (not sysopen $fh, $file, O_WRONLY|O_EXCL|O_CREAT) {
        say "\t($$: lock-file exists ..)";
        sleep 0.5;
    }   
    say $fh $pid;
}
sub release_lock {
    my ($file, $pid) = @_; 
    unlink $file or die "Error unliking $file: $!";
    say "\t($$: released lock)";
}

my @pids;
for (1..4) {
    my $pid = fork // die "Can't fork: $!";
    if ($pid == 0) {
        sleep rand 1;
        get_lock($lock_file, $$);
        say "$$, locked and processing";
        sleep rand 1;
        release_lock($lock_file, $$);
        say "$$ completed.";
        exit
    }   
    push @pids, $pid;    
}
wait for @pids;
最好使用lockfile名称,但要仔细阅读文档以了解细节

带有3个进程的示例输出

3659, locked and processing (3660: lock-file exists ..) (3658: lock-file exists ..) (3659: released lock) 3659 completed. 3660, locked and processing (3658: lock-file exists ..) (3658: lock-file exists ..) (3660: released lock) 3660 completed. 3658, locked and processing (3658: released lock) 3658 completed. 这些文件可以与
get\u lock
release\u lock
一起放置在模块中,例如,将锁文件名作为包全局名称

一个简单的测试驱动程序

# use statements as above
use Path::Tiny;           # only to show the file

my $lock_file = ".lock.file.access.$$"; 
my $file = 't_LOCK.txt';    
my @pids;
for (1..4) 
{
    my $pid = fork // die "Can't fork: $!";

    if ($pid == 0) {
        sleep rand 1;
        my $fh = open_with_lock($file, '>>');
        say "$$ (#$_) opening $file ..";
        say $fh "this is $$ (#$_)";
        sleep rand 1;
        close_and_release($fh);
        say "$$ (#$_) closed $file.";
        say '---';
        exit;
    }   
    push @pids, $pid;
}
wait for @pids;

print path($file)->slurp;
unlink $file;
使用第一个示例中的
语句,使用3个fork,运行

(18956: "lock"-file exists ..) # print out of order 18954 (#1) opening t_LOCK.txt ... (18955: "lock"-file exists ..) (18956: "lock"-file exists ..) (18955: "lock"-file exists ..) (18954: released lock) 18954 (#1) closed t_LOCK.txt. --- 18956 (#3) opening t_LOCK.txt ... (18955: "lock"-file exists ..) (18956: released lock) 18956 (#3) closed t_LOCK.txt. --- 18955 (#2) opening t_LOCK.txt ... (18955: released lock) 18955 (#2) closed t_LOCK.txt. --- this is 18954 (#1) this is 18956 (#3) this is 18955 (#2) (18956:“锁定”-文件存在..)#按顺序打印 18954(#1)正在打开t#u LOCK.txt。。。 (18955:“锁定”-文件存在..) (18956:“锁定”-文件存在..) (18955:“锁定”-文件存在..) (18954:释放的锁) 18954(#1)关闭了t#u LOCK.txt。 --- 18956(#3)正在打开t#u LOCK.txt。。。 (18955:“锁定”-文件存在..) (18956:释放的锁) 18956(#3)关闭了t#u LOCK.txt。 --- 18955(#2)打开t#u LOCK.txt。。。 (18955:释放的锁) 18955(#2)关闭了t#u LOCK.txt。 --- 这是18954(#1) 这是18956(#3) 这是18955(#2)
(请注意,独立进程正在为
STDOUT
而斗争)

哼,
flock
应该始终允许另一个线程获得锁,而不仅仅是“在压力下”。如果每个线程都有自己的文件句柄,这是真的吗?提供了有关flock如何以及何时能够在同一进程和同一个或不同fd中成功的更多详细信息。目前还不清楚:“描述符由flock()独立处理”和“一个进程在一个文件上只能持有一种类型的锁(共享或独占)。对已锁定文件的后续flock()调用将把现有锁转换为新的锁模式。因此,在同一进程中,当文件被另一个线程通过单独的文件描述符锁定时,是否应该阻止一个线程?NFS也是flock
存在的祸根。@mob sign。。。我在NFS上工作:(.当然,它有一些好的方面(但这些事情在我身上并不经常发生)@AndyH添加了锁定文件的具体示例access@zdim谢谢!您的解决方案不提供独占/共享锁功能,但我仍然可以将其用作临时修复程序,然后根据您的代码创建读写锁。@mpersico如果您的意思是为什么我没有将其作为一个模块呈现在这里,那是为了让它更简单。如果您提到CPAN…首先,谢谢你的好话。首先,我不确定它是否普遍有用(至少,要做到这一点需要更多的工作);此外,还需要做一些准备工作,以便在那里发布。但如果这被认为是有用的,我将很乐意这样做! (18956: "lock"-file exists ..) # print out of order 18954 (#1) opening t_LOCK.txt ... (18955: "lock"-file exists ..) (18956: "lock"-file exists ..) (18955: "lock"-file exists ..) (18954: released lock) 18954 (#1) closed t_LOCK.txt. --- 18956 (#3) opening t_LOCK.txt ... (18955: "lock"-file exists ..) (18956: released lock) 18956 (#3) closed t_LOCK.txt. --- 18955 (#2) opening t_LOCK.txt ... (18955: released lock) 18955 (#2) closed t_LOCK.txt. --- this is 18954 (#1) this is 18956 (#3) this is 18955 (#2)