2011-06-09 54 views
6

我有以下要求:我應該如何在Perl中實現原子序列?

  1. 序列是唯一的主機(沒有共享遞增是必要的)
  2. 序列必須單調增加。
  3. 序列必須在進程間保持不變。
  4. 在多個進程同時運行的情況下,遞增序列必須是原子的。
  5. 大部分時間文件將被更新,並在更新後讀取新值。但是,也應該可以在不更新的情況下讀取當前值。

我可以一起破解perl代碼,這將大致做到這一點,但我想要一個更優雅的解決方案。

+0

我一起黑客一起perl代碼,大致這樣做。將當前序列號存儲在文件中並在「flock」包裝器中訪問/更新它是否優雅? – mob 2011-06-09 19:54:13

+0

如果我不必親自編寫代碼,那麼它的確如此:) – 2011-06-09 20:27:34

回答

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)檢索序列號不改變它。

+0

這與我所做的大致相符。這將很好地完成。謝謝! – 2011-06-09 23:09:36

+0

爲什麼單獨的鎖定文件?爲什麼不打開文件讀/寫(''+ <'')和flock _it_? – cjm 2011-06-09 23:35:50

+1

cjm,請參閱http://perl.plover.com/yak/hw-nylug/samples/slide020.html和下面的幻燈片。 – daxim 2011-06-10 08:55:40

0

系統時間提供單調增加的順序,地址(2):

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

直到有人重置時鐘...

持久性(3)和incrementations的原子性(4)似乎需要一個鎖定數據庫。伯克利DB想到了。但是你可能正在尋找更簡單的東西,除非你已經在使用它了。沒有更新(5)的閱讀將是沒有問題的。單調增加的序列(2)也不會。

我不確定你的意思是「對主機唯一」和「共享增量」(1)。如果來自不同主機的序列元素具有相同的值,那麼您可以將該方法乘以所有服務器。否則,您只能通過網絡訪問其他人必須訪問的一個序列。

+0

好的嘗試,但是如果兩個進程在同一秒內碰到相同的庫代碼,它們可以很容易地具有相同的值。另外,它是不穩定的,所以你閱讀的價值與下一次的價值無關。 (#5) – Axeman 2011-06-09 20:00:18

+0

@Axeman - 系統時間不起作用,這很明顯。正如我寫的,有人重置時鐘。如果你可以排除這樣的時鐘擺動,這會讓你的序列失敗作爲一個副作用,你將不得不倒退的時間,如伯克利數據庫,其中提供#3,#4和#5。可能#1,但需要澄清。一旦你在那裏,你也可以選擇其他的東西作爲一個序列,可能只是一個整數。 – Lumi 2011-06-09 20:14:03

相關問題