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

我应该如何在Perl中实现原子序列?,perl,parallel-processing,atomic,sequences,Perl,Parallel Processing,Atomic,Sequences,我有以下要求: 序列对于主机是唯一的(不需要共享递增) 序列必须是单调递增的 该序列必须跨进程持久化 在多个进程同时处理序列的情况下,递增序列必须是原子的 大多数情况下,文件将被更新,更新后将读取新值。但是,也可以在不更新的情况下读取当前值 我可以将大致可以做到这一点的perl代码拼凑在一起,但我想要一个更优雅的解决方案。系统时间提供了一个单调递增的序列,它解决了(2): 直到有人重置时钟 增量的持久性(3)和原子性(4)似乎需要一个锁定数据库。我想到了伯克利DB。但是你可能正在寻找更简单的东西

我有以下要求:

  • 序列对于主机是唯一的(不需要共享递增)
  • 序列必须是单调递增的
  • 该序列必须跨进程持久化
  • 在多个进程同时处理序列的情况下,递增序列必须是原子的
  • 大多数情况下,文件将被更新,更新后将读取新值。但是,也可以在不更新的情况下读取当前值

  • 我可以将大致可以做到这一点的perl代码拼凑在一起,但我想要一个更优雅的解决方案。

    系统时间提供了一个单调递增的序列,它解决了(2):

    直到有人重置时钟

    增量的持久性(3)和原子性(4)似乎需要一个锁定数据库。我想到了伯克利DB。但是你可能正在寻找更简单的东西,除非你已经在使用它了。读取而不更新(5)不会有问题。单调递增序列(2)也不是


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

    将序列号存储在文件中,并使用
    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;
    }
    
    subset{#为序列号文件种子
    我的($file,$number)=@;
    打开我的$fh,“>”,$file;
    打印$fh$编号;
    }#隐式关闭
    分机{
    我的$file=shift;
    我的$incr=@#shift:1;#get($f)就像get($f,1)
    打开我的$lock,“>>”,“$file.lock”;
    flock$lock,2;
    
    打开我的$fh,'我已经拼凑了大致可以做到这一点的perl代码。将当前序列号存储在一个文件中并在
    flock
    包装器中访问/更新它是否算优雅?如果我不必自己编写代码,是的,它可以:)很好的尝试,但是如果两个进程在同一秒内命中相同的库代码,它们可以很容易获得相同的值。此外,它是易变的,因此您读取的值与下次读取的值几乎没有关系。(#5)@Axeman-很明显,系统时间并不完全起作用。正如我所写的,有人重置了时钟。如果你能排除对时钟的这种修补会导致序列失败的副作用,你就必须用类似Berkeley DB的东西来倒计时,它提供#3、#4和#5。可能还有#1,但这需要澄清。一旦在这里,您还可以选择其他内容作为序列,可能只是一个整数。这大致与我所做的匹配。这将很好。谢谢!为什么要单独锁定文件?为什么不直接以读/写方式打开文件(
    ”+cjm,请参阅和下面的幻灯片。@daxim,我不确定这是否真的适用于这里。通常情况下,在文件保持锁定的同时读取、递增和写入。
    truncate
    不是问题,因为序列在增加;新的数字将始终至少与前一个数字一样长。我希望seek更有效比关闭和重新打开更方便(加上锁文件的额外打开)。
    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;
    }