我使用 Mojo::IOLoop 与端口通信以向数字接收器发送命令。
因为接收器只能打开一次端口,但与其通信的代码位于网络界面和网络服务器后面,因此存在命令被同时发送的风险 - 因此数字接收器会丢失它们,事情就会出错.
那么 - 我怎样才能确保某些代码永远不会同时运行?
我试图像这样使用文件锁:
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);
});
}
最佳答案
我不确定我是否正确理解你想做什么,因为我不熟悉 Mojo。但是如果你只是不想执行一个函数两次创建一个锁定文件并在它完成时删除:
use File::Slurp;
sub my_method_to_execute_only_once {
my $tmp = 'temp.txt';
return if (is_method_running($tmp));
# DO YOUR STUFF
unlink $tmp;
}
sub is_method_running{
my ($filename) = @_;
if (-e $tmp){
return 1;
}
write_file($tmp, "running");
return 0;
}
https://stackoverflow.com/questions/64964281/