いいえ、リーダーのプログラムフローが正しくありません。 1つ以上の読み取りが進行中のときに書き込みを防止するためのロック機構と、書き込みが完了するたびに読み取り機に通知するための何らかの種類の起動機構が必要です。
ライター(S)のためのあなたのプログラムの流れは大丈夫です:
# Initial read of file contents
Obtain lock
Read file
Release lock
# Whenever wishes to modify file:
Obtain lock
Modify file
Signal readers
Release lock
リーダー(S)のためのプログラムの流れは次のようになります。
# Initial read of file contents
Obtain lock
Read file
Release lock
# Wait and respond to changes in file
On signal:
Obtain lock
Read file
Release lock
Do something with modified file contents
一つだけがある場合共有メモリ(すべてのライターとリーダーにアクセス可能)のミューテックス(pthread_mutex_t
)で十分です。それ以外の場合は、代わりにrwlock(pthread_rwlock_t
)を使用することをお勧めします。待機中の読者を目覚めさせるために、条件変数(pthread_cond_t
)でブロードキャストします。もちろん、難しいことは、その共有メモリを設定することです。
アドバイザリファイルロックとfanotifyインターフェイスでも十分です。読者はfanotify FAN_MODIFY
マークをインストールし、対応するイベントを待つだけです。ライターは、アドバイザリーロック(ファイルが変更されている間に読者の読書を止めるためにのみ存在する)の使用を除いて、協力する必要はありません。
現在のところ、インターフェイスにはCAP_SYS_ADMIN
の機能が必要です。この機能は、ランダムCGIプログラムには望ましくありません。
アドバイザリファイルロッキングおよびinotifyインターフェースが十分であり、そして両方のリーダとライタオープンとは、操作のセットごとにファイルを閉じるとき、私は、このための最も適切と考えています。リーダー(S)のために、この場合のプログラムの流れは次のとおりです。
Initialize inotify interface
Add inotify watch for IN_CREATE and IN_CLOSE_WRITE for "file"
Open "file" read-only
Obtain shared/read-lock
Read contents
Release lock
Close "file"
Loop:
Read events from inotify descriptor.
If IN_CREATE or IN_CLOSE_WRITE for "file":
Open "file" read-only
Obtain shared/read-lock
Read contents
Release lock
Close "file"
Do something with file contents
ライターライターがロックを取得していない場合であっても、読者は時に通知されますまだちょうど
# Initial read of file contents
Open "file" for read-only
Obtain shared/read-lock on "file"
Read contents
Release lock
Close "file"
# Whenever wishes to modify file:
Open "file" for read-write
Obtain exclusive/write-lock
Modify file
Release lock
Close "file"
ですライターはファイルを閉じます。唯一のリスクは、読者がファイルを読み込んでいる間に別の変更セットが(別のロック・スパーリング・モディファイアによって)書き込まれることです。
修飾子でファイルを新しいものに置き換えた場合でも、新しいものが用意できたら、読者は正しく通知されます(古いファイルの上に改名/リンクされるか、新しいファイル作成者がファイルを閉じます)。読者がファイルを開いたままにしておくと、ファイル記述子が新しいファイルに魔法のようにジャンプすることはなく、古い(おそらく削除された)内容のみが表示されることに注意することが重要です。
それは読者や作家が読者がまだinotifyを使用することができ、ファイルを閉じていないが、ファイルが切り捨てられるかに書き込まれるたびIN_MODIFY
マークではなく、通知することが重要何らかの理由である場合。この場合、ファイルが置き換えられる(名前が変更された、または削除されて再作成される)と、読者とライターは新しいファイルを見ることはできませんが、古い、現在は見えない-filesystemファイルの内容。
リーダーのためのプログラムの流れ:
Initialize inotify interface
Add inotify watch for IN_MODIFY for "file"
Open "file" read-only
Obtain shared/read-lock
Read contents
Release lock
Loop:
Read events from inotify descriptor.
If IN_CREATE or IN_CLOSE_WRITE for "file":
Obtain shared/read-lock on "file"
Read contents
Release lock
Do something with file contents
作家のためのプログラムの流れは依然としてほぼ同じである:
# Initial read of file contents
Open "file" for read-only
Obtain shared/read-lock on "file"
Read contents
Release lock
Close "file"
Open "file" for read-write
# Whenever writer wishes to modify the file:
Obtain exclusive/write-lock
Modify file
Release lock
はそれが重要であるかもしれないが注意することはinotifyイベント事実の後に起こる。通常、マシンの負荷に依存する可能性のある小さな待機時間があります。したがって、システムが正常に動作するためにファイルの変更に対する迅速な対応が重要な場合は、代わりにmutexまたはrwlockと共有メモリの条件変数を使用する必要があります。
私の経験では、これらの待ち時間は典型的な人間の反応間隔よりも短くなる傾向があります。したがって、私は、あなたがそうすることをお勧めします - 人間のタイムスケールで十分に高速かつ信頼できるinotifyインターフェイス。ミリ秒単位とミリセカンド単位のマシンタイムスケールではそうではありません。
ミューテックスの代わりにセマフォを使用できます。 – Riley
プロセス間通信が必要です。あなたのアドホックなスキームではなく、Linuxの名前付きパイプや[ZeroMQ](http://czmq.zeromq.org/)を読むことをお勧めします。 – orlp
私が指摘した競争条件については、どちらのコメントも対応していません。私はセマフォについて知っている、私はIPCについて知っている。 –