Как мне реализовать атомарную последовательность в Perl? - PullRequest
6 голосов
/ 09 июня 2011

У меня есть следующие требования:

  1. Последовательность является уникальной для хоста (нет необходимости в общем приращении)
  2. Последовательность должна монотонно увеличиваться.
  3. Последовательность должна быть постоянной во всех процессах.
  4. Увеличение последовательности должно быть атомарным в случае одновременной работы нескольких процессов.
  5. Большую часть времени файл будет обновлятьсяи новое значение читается после обновления.Но также должно быть возможно прочитать текущее значение без обновления.

Я могу взломать Perl-код, который примерно с этим справится, но я бы хотел более элегантное решение.

Ответы [ 2 ]

5 голосов
/ 10 июня 2011

Сохраните порядковый номер в файле и используйте 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), чтобы получить порядковый номер без его изменения..

0 голосов
/ 09 июня 2011

Системное время обеспечивает монотонно возрастающую последовательность, которая обращается (2):

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

Пока кто-то не сбросит часы ...

Постоянство (3) и атомарность приращений (4), по-видимому, требуют блокировки базы данных. Беркли DB приходит на ум. Но вы можете искать что-то попроще, если вы все равно уже этим не пользуетесь. Читать без обновления (5) не будет проблем. Монотонно возрастающая последовательность (2) тоже не будет.

Я не уверен, что вы подразумеваете под "уникальным для хоста" и "общим приращением" (1). Если все элементы последовательности с разных хостов могут иметь одинаковое значение, вы можете умножить подход ко всем серверам. В противном случае вы можете иметь только одну последовательность, которая должна быть доступна другим через сеть.

...