如何确保函数在perl中永远不会并发执行?
我使用Mojo::IOLoop与端口通信,以向数字接收器发送命令 因为接收者只能打开端口一次,但与之通信的代码位于web界面和web服务器的后面,因此存在同时发送命令的风险——因此数字接收者会丢失这些命令,从而出现问题 那么,如何确保某些代码永远不会并发运行呢 我试着像这样使用文件锁:如何确保函数在perl中永远不会并发执行?,perl,Perl,我使用Mojo::IOLoop与端口通信,以向数字接收器发送命令 因为接收者只能打开端口一次,但与之通信的代码位于web界面和web服务器的后面,因此存在同时发送命令的风险——因此数字接收者会丢失这些命令,从而出现问题 那么,如何确保某些代码永远不会并发运行呢 我试着像这样使用文件锁: sub enqueue { my $self = shift; my ($cmd, $promise) = @_; while (!(flock DATA, LOCK_EX|LOCK_N
sub enqueue {
my $self = shift;
my ($cmd, $promise) = @_;
while (!(flock DATA, LOCK_EX|LOCK_NB)) { sleep(0.25) }
my (@r);
my $id = Mojo::IOLoop->client({ address => '192.168.1.204',
port => 23, timeout => 13 }
=> sub ($loop, $err, $stream) {
return $promise->reject('could not open stream') unless $stream;
$stream->on(error => sub ($stream, $err) {
flock(DATA, LOCK_UN);
$stream->close;
$promise->reject($err);
});
$stream->on(read => sub ($stream, $bytes) {
$bytes =~ s/\r\n$//;
push @r, split /\r\n/, $bytes;
# stream done is a function that checks that
# the appropriate number of lines got sent back
if (stream_done(@r)) {
flock(DATA, LOCK_UN);
$promise->resolve(\@r);
$stream->close;
};
});
$stream->on(timeout => sub ($stream) {
flock(DATA, LOCK_UN);
$stream->close;
$promise->reject('timeout') if ($err);
});
$stream->write($cmd);
});
}
我不确定我是否正确理解你想做什么,因为我不熟悉魔咒。但如果您只是不想执行函数两次,请创建一个锁文件,并在完成时删除:
使用File::Slurp;
将我的方法分为只执行一次{
my$tmp='temp.txt';
如果(方法正在运行($tmp)),则返回;
#做你的事
取消$tmp的链接;
}
sub正在运行{
我的($filename)=@;
如果(-e$tmp){
返回1;
}
写_文件($tmp,“running”);
返回0;
}
我会重新设计这个问题,这样就只有一件事可以与接收器对话。web进程只与一个对象通信,因为它是唯一与接收者通信的对象,不需要与任何人协调。例如,想想syslog是如何工作的。@briandfoy-所以我一直在思考这个问题,但却被困在一块岩石和一个坚硬的地方之间。由于从接收器返回响应的方式,我只能通过异步的Mojo::IOLoop使其工作,因此很难避免并发。我还试图用一个队列来做这件事,但完全搞砸了。可能是我的架构出错了——这并不奇怪,因为我不是专业人士,这是我第一次尝试(相对而言)低级别的网络协议