我应该如何在Perl中实现原子序列?

时间:2011-06-09 19:22:15

标签: perl parallel-processing atomic sequences

我有以下要求:

  1. 序列对于主机是唯一的(不需要共享递增)
  2. 序列必须单调递增。
  3. 序列必须在各个流程之间保持一致。
  4. 在多个进程同时处理的情况下,递增序列必须是原子序列。
  5. 大多数情况下文件都会更新,更新后会读取新值。但是,也应该可以在不更新的情况下读取当前值。
  6. 我可以将perl代码一起破解,但是我想要一个更优雅的解决方案。

2 个答案:

答案 0 :(得分:5)

将序列号存储在一个文件中,并使用flock确保只有一个进程可以访问它:

sub set {     # seed the sequence number file
    my ($file, $number) = @_;
    open my $fh, '>', $file;
    print $fh $number;
}  # implicit close

sub get {
    my $file = shift;
    my $incr = @_ ? shift : 1;   # get($f) is like get($f,1)
    open my $lock, '>>', "$file.lock";
    flock $lock, 2;
    open my $fh, '<', $file;
    my $seq = <$fh>;
    close $fh;
    set($file, $seq+$incr) if $incr;   # update sequence number
    close $lock;
    return $seq;
}

您可以将其称为get($file,0),以便在不更改序列号的情况下检索序列号。

答案 1 :(得分:0)

系统时间提供单调递增的序列,其地址为(2):

perl -MTime::HiRes=time -lwe "print time"

直到有人重置时钟......

持久性(3)和递增的原子性(4)似乎需要一个锁定数据库。 Berkeley DB浮现在脑海中。但是你可能正在寻找更简单的东西,除非你已经在使用它了。没有更新(5)的读取将没有问题。单调增加的序列(2)也不会。

我不确定你所说的“主机独有”和“共享增量”(1)。如果来自不同主机的序列元素可以具有相同的值,那么您可以将该方法与所有服务器相​​乘。否则,您只能拥有一个必须通过网络访问的序列。