2017-08-19 25 views
0

問題:Linuxプラットフォームでは、新しいファイルを作成するか、既存のファイルを上書きして、他のプロセスが読み取り専用で開くようにします。このような何かを行うことができCreateFile 1を使用した:それは同様の旗を持つ別のプロセスによって開かれた場合Linuxファイルのロック

CreateFile("blah.log", GENERIC_WRITE, FILE_SHARE_READ, 
      NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

この呼び出しは失敗しても、既存のファイルを上書きします。

Linuxで同様の動作を達成するにはどうすればよいですか?すべてのプログラムがアドバイザリロックを尊重しているとします。

+0

[タグ:C++]タグと[タグ:c]タグの両方を使用しましたが、コードはC++ ** OR ** Cのみ可能です。あなたは1つの質問をしなかった、あなたはただ問題を述べたので、これは残念ながら不明です。 **あなたは明確な質問をする必要があります**、最後に疑問符をつけて、私たちが明確に答えることができるようにしてください。 –

+0

これはちょっとした問題です。あなたがしようとしていることの詳細*を追加する必要があります。 Linuxでは適切な*必須のファイルロックはありません - ロックは助言のみです - つまり、悪いプログラムが無視することができます - これはあなたに適していますか? –

+0

@MarcusMüller実際には、この言語はあまり意味がありません.Linuxシステムコールのセマンティクスはより適切です。 –

答えて

0

openとアドバイザリflockを使用すると、ライターはLOCK_EX排他ロックを保持する必要があります。読者を保有してはならず、のいずれかがにロックされていてはならず、ファイルが突然切り捨てられることがあります。

プレーンfopenは読者に使用できます。あなたはその上からファイルを<stdio.h>ルーチンを使用する場合について作家、

#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/file.h> 
#include <fcntl.h> 
#include <stdio.h> 

// never truncates 
int fd = open("foo.log", O_CREAT|O_WRONLY /*or O_RDWR */, 0644 /* mode */); 
if (flock(fd, LOCK_EX|LOCK_NB) != 0) { 
    perror("Locking failed - I am not an exclusive writer"); 
    exit(1); 
} 

// I hold the exclusive lock - now, truncate the file to 0 bytes 
ftruncate(fd, 0); 

(他のエラーが簡潔にするため省略チェック)

をよく振る舞い、あなたはfdopen使用することができます。

// "w" will not truncate! 
FILE *f = fdopen(fd, "w"); // or `r+` for O_RDWR... 

リーダはファイルにLOCK_SHロックを設定してはいけません。そうでなければ、エル。

0

あなたはflocklockf機能を探しています:)

これのほとんどは、非常に多くのman 2 flockman lockfに基づいているので、私は心からそれを読んでお勧めします。

これはman lockf

#include <unistd.h> 

int lockf(int fd, int cmd, off_t len); 

...

説明

から、適用テストまたは開いているファイルのセクションのPOSIXロックを削除しています。ファイルはfdによって指定され、ファイルディスクリプタは の書き込み、cmdによるアクション、およびセクションはバイトポジションpos..pos + len-1(lenが正の場合)、およびpos-len..pos-1 lenが負の場合、posは現在のファイル の位置であり、lenがゼロの場合、セクションは現在のファイル位置 の現在のファイル位置から、現在および将来のファイルの終わりの位置までを含む無限大に拡張されます。すべての場合において、セクションは現在のファイルの最後まで を拡張することができます。

Linuxの場合、lockf()は、fcntl(2)ロックの上にあるインタフェースに過ぎません。他の多くのシステムでは、 のようにlockf()を実装していますが、POSIX.1では lockf()fcntl(2)の間の関係が未定義になっています。移植可能なアプリケーションはおそらく、これらのインタフェースへの呼び出しを混ぜることを避けるべきです。

有効な操作は以下の通りである:

  • F_LOCKは、ファイルの指定されたセクションに排他ロックを設定してください。このセクションの(一部)が既にロックされている場合、呼び出しは前回のロックが解除されるまでブロックされます。このセクションが以前にロックされたセクションと重なっている場合、両方がマージされます。ファイルロックは、ロックを保持するプロセスがファイルのファイル記述子を閉じるとすぐに解放されます。子プロセスはこれらのロックを継承しません。
  • F_TLOCKF_LOCKと同じですが、ファイルが既にロックされていると、呼び出しはブロックされず、エラーを返します。
  • F_ULOCKファイルの示されたセクションのロックを解除します。これにより、ロックされたセクションが2つのロックされたセクションに分割されることがあります。
  • F_TESTロックをテストする:このプロセスによって指定されたセクションがロック解除またはロックされている場合は0を返し、他のプロセスがロックを保持している場合は-1を返し、errnoEAGAIN(他のシステムではEACCES)と設定します。

しかし、それがすっごく、単一ライター、マルチリーダのケースのために本当に適した唯一の排他的ロックではありません。

私はUNIXソケット(man unix)を見ています。ファイルやソケットのように動作します(ソケットですが、file-io関数を使用することができます)。また、他の誰かが既に所有しているソケット(通常のファイルのようにファイルシステムに存在する可能性があります)失敗します。

あなたがやろうとしていることは、IPC(プロセス間通信)とよく似ていますが、シンプルな共有メモリコーディネーションを見たいと思うかもしれません。 shmgetなどのようなものを使用すると、非常にファイル的なやり方で物を開くことができ、ディスクにデータを書き込む際のペナルティを招くことなく、高いパフォーマンスでプロセス間でデータを直接交換できます。 (実際のファイルをメモリにmemmappingしても同じことができますが、ロックの問題は解決しません)。

しかし、これらはIPC問題に対する非常に低いレベルのアプローチです。実際にはIPCライブラリを使用することをお勧めします。大規模でクラスタ化されたシステムの場合、非常に素敵なソケットベースのシステムの場合、またはソケットに似た柔軟なシステムの場合(zeroMQが念頭に置かれます)、異なるシステムのニーズに合ったシステムがあります。

関連する問題