ファイル同時アクセス

[戻る]
ららら [E-Mail] 2001/03/07(水) 14:16:30
マルチスレッドで
一方のスレッドで
File *fp
fp = fopen( psPath,"rb"))
で開きます。
そしてcloseする前に、
別スレッドで
CFileの
CFile::modeRead | CFile::typeBinary
でOpneすると失敗します。

しかし、このCFileを
File *fp
fp = fopen( psPath,"rb"))
方式に書き換えると
オープンできます。

CFile::shareDenyNoneをつければ逆ならできるのでしょうが
fopenで開いて、CFileで開くをやりたいのです。

CFileのままで
オープンする方法はありますでしょうか。
ご教授ください。

ku 2001/03/07(水) 14:58:37
fopenは内部で_SH_DENYNOを使用していて
CreateFileを呼ぶときに必ず
FILE_SHARE_READ | FILE_SHARE_WRITEを渡します。

CFileの方はCFile::share関係のフラグを何も設定しないと
CFile::shareExclusiveと同じ状態になります。
なので既にオープンされているとエラーとなります。
CFile::shareDenyNoneをフラグに追加指定すれば大丈夫です。
CFile::shareDenyNoneだと
CreateFileを呼ぶときにFILE_SHARE_READ | FILE_SHARE_WRITEを渡します。

fopen->CFileの順でもうまくいくはずです
しかし、同じ機能を複数の実装ライブラリを使用するのは感心しません。
どちらか一つに統一した方がよいと思います。
「結局はCreateFileだろ」なんてライブラリのソースまで熟知しているのなら
何ももうしませんが。

ららら [E-Mail] 2001/03/07(水) 15:40:55
返信ありがとうございます。

>fopenは内部で_SH_DENYNOを使用していて
>CreateFileを呼ぶときに必ず
>FILE_SHARE_READ | FILE_SHARE_WRITEを渡します。
まず、fopenは、内部でCreateFileは呼んでいませんよね。
上記と等価ということですかね。

また、shareDenyNoneをつけて、
CFileでひらいてfopenなら開けそうですが
今回の件のfopenで開いてCFileで開くはできないようです。

>しかし、同じ機能を複数の実装ライブラリを使用するのは感心しません。
>どちらか一つに統一した方がよいと思います。
できれば、おっしゃるとおりにしたいのですが
同じファイルを利用するだけで違う機能なんです。
また、このシステムは何十万ステップにもわたるもので複数の人間で
作成しています。よってそれぞれもレベルもまちまちで
かなり各自の好きなように作られています。(ただまとまっていないともいうかもしれませんが)
対処方法としては、
1.CFileをfopenに変える。
2.fopenをCFileに変えてshareDenyNone指定
3.fopenをfsopenに変える
という案があがっています。
もう少し原因をつめてみようと思います。

ku 2001/03/07(水) 15:56:26
> まず、fopenは、内部でCreateFileは呼んでいませんよね。
では何を呼んでいるのでしょうか?
VCのインストール時にCRT関数のソース(どうゆう表記だったかは忘れました)
をインストールすれば、Cの標準関数のソースを見ることができます。
少なくとも僕が持っている環境ではfopenはCreateFileを使用していました。
VC以外のC言語環境のfopenがどういった実装をしているかは知りません。

僕はこのコメントを付けるときにプログラムを作って試したのだけど
信用してもらえないのかなぁ?。
考えるより実際に試した方が早いんですけどね
こんな感じです。
char szFileName[] = "c:\\a.txt";
FILE* fp = fopen(szFileName, "rb");
if (fp != NULL) {
    CFile file;
    file.Open(szFileName,
        CFile::shareDenyNone | CFile::modeRead | CFile::typeBinary);
    fclose(fp);
}

ららら [E-Mail] 2001/03/07(水) 16:43:35
[[解決]]
たしかに、open.cというファイルで
fopenは、CreateFileによって実装されていました。
先入観というやつでした。DOSなどの場合は違う実装方法が
されていたということですね。失礼致しました。
また勉強になりました。

それに、なんとCFile::shareDenyNone でできてしまいました。
これも申し訳ないです。
最初にテストしたときにできなかったもので。
(おそらく、自作ライブラリののリンクミスだと思います。)

テストプログラムまで動作確認までやっていただいていたとは。
感謝します。

古いスレッドには追加発言できません。