複数スレッドからファイルアクセスする場合の、適切なロック方法


C言語で複数スレッドからファイルアクセスする場合、ロックする関数についてご教示ください。

下記のようなプログラムを作成しています。

・スレッド(1)は、ファイルに対してライトします。  
・スレッド(2)は、スレッド(1)によってライトされたファイルに対してリードします。  
・必ずしもスレッド(1)(2)は同じファイルにアクセスするわけではなく、スレッドごとにfopen()します。  
・タイミングによってスレッド(1)(2)は同じファイルにアクセスします。

・（不測の自体でロックをとったままスレッドが落ちてしまった場合、他方のスレッド側ロックを強制解除して処理は継続させたいです（別途エラーメッセージはログに出力します）。

flock(fd,LOCK_EX)をつかってロックを取る方針で検討していたのですが、  
「flock()はファイル記述子ごとにロックするので、  
fopen()を別々に行っていては正しくロックできないのでは？」  
との指摘を受けて、ロックのとり方を再検討している最中です。




Linuxではあまり役に立たないかもしれませんが

C11で導入された[`fopen_s()`](http://en.cppreference.com/w/c/io/fopen)を使用すると排他オープンすることができます。ファイルシステムレベルでの排他なので別プロセス・別スレッドだけでなく同一スレッドであってもクローズするまでは再オープンすることができなくなります。

ただし、先行するファイル使用者がいつ完了するのか？という問題があります。完了待ちをすることを考えるとuser20098さんの提案されている`pthread_mutex_lock`などの排他・同期が適切に感じます。

* * *

> もスレッド(1)(2)は同じファイルにアクセスするわけではないので、mutexだと若干ロッ‌​ク範囲がおおきくなります。

ファイル毎にmutexを作成するまでです。ファイル名・mutexのペアを構造体で用意し、スレッド間で共有することになるでしょうか。  
というように適切な設計を行っていくと

> スレッド毎にfopen()して、できればスレッド間でファイルディスクリプタの受け渡しはしたくな‌​いです。

などとは言っていられないです。

* * *

> 排他を取るのはシングルプロセスです。

とのことですが、ファイルを書き込むのも読み込むのも単一プロセス内ということでしたら、そもそもファイルを介さず、プロセス内スレッド間でメモリを共有すればいいのではと思います。




Linuxではあまり役に立たないかもしれませんが

C11で導入された[`fopen_s()`](http://en.cppreference.com/w/c/io/fopen)を使用すると排他オープンすることができます。ファイルシステムレベルでの排他なので別プロセス・別スレッドだけでなく同一スレッドであってもクローズするまでは再オープンすることができなくなります。

ただし、先行するファイル使用者がいつ完了するのか？という問題があります。完了待ちをすることを考えるとuser20098さんの提案されている`pthread_mutex_lock`などの排他・同期が適切に感じます。

* * *

> もスレッド(1)(2)は同じファイルにアクセスするわけではないので、mutexだと若干ロッ‌​ク範囲がおおきくなります。

ファイル毎にmutexを作成するまでです。ファイル名・mutexのペアを構造体で用意し、スレッド間で共有することになるでしょうか。  
というように適切な設計を行っていくと

> スレッド毎にfopen()して、できればスレッド間でファイルディスクリプタの受け渡しはしたくな‌​いです。

などとは言っていられないです。

* * *

> 排他を取るのはシングルプロセスです。

とのことですが、ファイルを書き込むのも読み込むのも単一プロセス内ということでしたら、そもそもファイルを介さず、プロセス内スレッド間でメモリを共有すればいいのではと思います。

