C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[55]: ディレクトリの排他アクセス [5]


(過去ログ 40 を表示中)

[トピック内 142 記事 (101 - 120 表示)]  << 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 >>

■20471 / inTopicNo.101)  Re[37]: ディレクトリの排他アクセス
  
□投稿者/ す (35回)-(2008/06/10(Tue) 23:34:00)
No20463 (れい さん) に返信
> >>「エントリ名,エントリ種別(ファイル/ディレクトリ),更新日時,アクセス日時,…」
> >>というように、エントリ毎のレコードにする必要があります。
> >>エントリのテーブルをディレクトリ毎に作るべきです。
>>
>>そんな感じです。
>
> ならば「ファイルもしくはディレクトリを開く」ことを
> 「レコードを開く」と対応させるのですよね。

いいえ。なんでそうなるのか分かりません。

レコードには、メタ情報やファイルやディレクトリ実体へのポインタがあるだけで、
開くのはファイルやディレクトリ実体であって、レコードではありません。


引用返信 編集キー/
■20472 / inTopicNo.102)  Re[38]: ディレクトリの排他アクセス
□投稿者/ れい (640回)-(2008/06/11(Wed) 00:12:08)
2008/06/11(Wed) 00:13:42 編集(投稿者)

No20471 (す さん) に返信
>>ならば「ファイルもしくはディレクトリを開く」ことを
>>「レコードを開く」と対応させるのですよね。
>
> いいえ。なんでそうなるのか分かりません。
>
> レコードには、メタ情報やファイルやディレクトリ実体へのポインタがあるだけで、
> 開くのはファイルやディレクトリ実体であって、レコードではありません。

なるほど!
そう考えているのですか。

その「メタ情報」というのは、Windowsで言えば「更新日時」や「ファイル属性」などですよね?
で、CreateFileは「実体」を開いていると思ってるわけですね。

それはWindowsにおいては違います。

Windowsではファイル本体へのアクセスだけでなく、メタ情報へのアクセスでも「ハンドルを開く」必要があります。
ですので、Windowsでは「ファイルを開く」というのは「レコードを開く」というのに対応します。
開く際の共用モードは、レコードへのアクセスの共用モードに対応します。
(同様に、「ディレクトリを開く」というのも、「レコードを開く」というのに対応してます。)
「ファイルの実体」へのアクセスは関係ありません。
少なくとも、ファイルシステムはそう実装されています。

どうしてそうなっているのか、という話になると長くなりますが。

一つの理由が共用モードをファイル自体(=ファイルのストリーム)の整合性を保つほかに、
メタ情報の整合性を保つ用途にも使えるからです。
(操作を他プロセスに対してアトミックに実行することができる)

例えば「更新日時とアクセス日時を同じにしたい」という操作は、
1 対象のファイルをCreateFileで排他的に開く
2 アクセス日時を読む
3 更新日時を更新する
4 ハンドルを閉じる
といった順になります。

しかし、同じようにメタ情報を持っているはずのディレクトリに対しては、これができません。
CreateFileでは排他で開けないのです。(NtCreateFileならOK)

もし す さんの言うように「ファイルを開く=ファイルの実体を開く≠レコードを開く」となってるのであれば、
メタ情報へのアクセスで同期制御できません。
「更新日時とアクセス日時を同じにしたい」場合はどうしますか?

引用返信 編集キー/
■20475 / inTopicNo.103)  Re[39]: ディレクトリの排他アクセス
□投稿者/ す (36回)-(2008/06/11(Wed) 02:11:26)
No20472 (れい さん) に返信
> そう考えているのですか。
>
> その「メタ情報」というのは、Windowsで言えば「更新日時」や「ファイル属性」などですよね?
> で、CreateFileは「実体」を開いていると思ってるわけですね。
>
> それはWindowsにおいては違います。
>
> Windowsではファイル本体へのアクセスだけでなく、メタ情報へのアクセスでも「ハンドルを開く」必要があります。

あれ、そうなんですか。
でも、「メタ情報」はディレクトリ側に持ってるんですよね?
それを見るのにもファイルをオープンしないといけないんですか?

引用返信 編集キー/
■20476 / inTopicNo.104)  Re[40]: ディレクトリの排他アクセス
□投稿者/ れい (641回)-(2008/06/11(Wed) 02:31:25)
No20475 (す さん) に返信
> あれ、そうなんですか。
> でも、「メタ情報」はディレクトリ側に持ってるんですよね?

いいえ。
ディレクトリ側には持っていません。
ディレクトリもメタ情報をもってますが、それはディレクトリ自身のメタ情報です。

> それを見るのにもファイルをオープンしないといけないんですか?

そうです。

以下はNTのファイルシステムの話です。

「c:\aaa\tmp.exe」という場合、
c:\aaa\tmp.exeのファイル属性や更新日時などのメタ情報はc:\aaa\tmp.exeが持っています。
c:\aaaのファイル属性や更新日時などのメタ情報はc:\aaaが持っています。

で、「見る」場合は二通り方法があります。

「c:\aaa\tmp.exe」のメタ情報を「見る」には二通り方法があり、
「c:\aaa\tmp.exe」のハンドルを開いて取得するか、
「c:\aaa」を開いてディレクトリ一覧を見て、そこから取得します。

「c:\aaa\tmp.exe」のメタ情報を「更新する」には
「c:\aaa\tmp.exe」のハンドルを開いて更新するしかありません。

で、Vistaより前のWin32APIだと、

「c:\aaa\tmp.exe」のAttributeを「見る」「書く」には…
「エントリ名」を指定してGetFileAttribute/SetFileAttributeを使います。

「c:\aaa\tmp.exe」の更新日時などを「見る」「書く」には…
「ハンドル」を指定してGetFileTime/SetFileTimeを使います。

Vista以降だと、Attributeに関しても「ハンドル」を用いて「見る」「書く」ことができます。

引用返信 編集キー/
■20477 / inTopicNo.105)  Re[41]: ディレクトリの排他アクセス
□投稿者/ す (37回)-(2008/06/11(Wed) 02:42:16)
No20476 (れい さん) に返信
> 「c:\aaa」を開いてディレクトリ一覧を見て、そこから取得します。
というのは、
>>でも、「メタ情報」はディレクトリ側に持ってるんですよね?
ということで
>>それを見るのにもファイルをオープンしないといけないんですか?
しなくてよいということではないのですか?

引用返信 編集キー/
■20478 / inTopicNo.106)  Re[41]: ディレクトリの排他アクセス
□投稿者/ れい (642回)-(2008/06/11(Wed) 03:06:54)
あー。もう全然わからなくなりました。
APIを眺めていて気づいたんですが。

不思議なのは「ディレクトリエントリの列挙」だけではありませんでした。

FindFirstFileが「エントリ名」を取ることが疑問だったわけですが、
かなり新しいAPIである、「FindFirstStream」も「FindFirstFileName」も、
「ファイル名」を引数に取るのにようやく気づきました。

これらのAPIを用いる限りでは
「あるファイルの全てのサブストリームをメインストリームにまとめた上で削除」
とか
「HardLinkされてるファイル名を全部同じ名前にする」
といった操作が正しくできないことを意味します。

SetInformationByHandleをVistaで導入しているのに、
StreamやHardLinkに対して「ファイル名指定」で操作を行うようにしたというのは、
「歴史的事情」以外に何か意図・思想があると感じます。

FindFirstFile、FindFirstFileName、FindFirstStreamで
「ファイル名」を指定する理由は何でしょう?
なぜ「ハンドル」ではいけなかったのでしょう?

APIの形式を伝統的なFindFirstFileに合わせた、
より強力なTxFが導入されたので別に問題ないということになった、
という見方もできなくはないですが…

カーネルレベルではエントリ列挙もハードリンク列挙もストリーム列挙も「ハンドル」で行われています。
TxFは非常にコストがかかります。
外部仕様としては、LPWSTRとHANDLEの違いだけです。

やっぱり私は何か見落としをしてる気がしてなりません。
FindXXXにはなにか重要な設計思想があるのではないでしょうか?
引用返信 編集キー/
■20479 / inTopicNo.107)  Re[42]: ディレクトリの排他アクセス
□投稿者/ れい (643回)-(2008/06/11(Wed) 03:08:50)
No20477 (す さん) に返信
> ■No20476 (れい さん) に返信
>>「c:\aaa」を開いてディレクトリ一覧を見て、そこから取得します。
> というのは、
> >>でも、「メタ情報」はディレクトリ側に持ってるんですよね?
> ということで

だから違います。
持っていません。

> >>それを見るのにもファイルをオープンしないといけないんですか?
> しなくてよいということではないのですか?

一部のメタ情報のみ、親のハンドルから見ることが出来ますが、
書き込めません。
引用返信 編集キー/
■20480 / inTopicNo.108)  Re[43]: ディレクトリの排他アクセス
□投稿者/ ネタ好き (426回)-(2008/06/11(Wed) 05:43:32)
れいさんの言っている事は分かるのですが、やはり私が以前言った階層のロック問題を解決しない限り、開発者ユーザにAPIを開放するのは企業的に危険であるといっているのです。おまけにWindowsはAPIを抽象化し、「開発者に楽をさせる」方針を採っていますので、UNIX系OSのように薄い階層を持つ構造とは違って、開発者に何らかの意図的な手順を踏ませるわけです。
WindowsOSがディレクトリとファイルを同一に扱うのは【効率】的であるからであって、APIとして公開する部分については【概念】を提供しているわけですから、ディレクトリとファイルの扱いに明確に一線を引いているのではないかと私は推測しています。 
引用返信 編集キー/
■20481 / inTopicNo.109)  Re[43]: ディレクトリの排他アクセス
□投稿者/ れい (644回)-(2008/06/11(Wed) 06:12:40)
申し訳ないです。
まじめに検証したらいくつか「嘘」がありました。
(分かってたはずなのに、すぐに忘れてしまうのがダメですねぇ…)

1 メタ情報の更新について。

メタ情報に関しては、ファイル/ディレクトリに関わらず、
「共用アクセス制御」は効きませんでした。
少なくともFATとNTFSにおいては。
(忘れてた…)

2 FindFirstFileName、FindFirstStream

HardLinkの列挙も、Streamの列挙も、「列挙のみ」ならば常に可能でした。
HardLinkの作成は作成先で作成許可が必要なだけ、
Streamの共用アクセス制御はファイル単位で行います。
ですので、FindFirstFileNameとFindFirstStreamはNTFSやFATの機能を十分に満たしていました。

ただ、ディレクトリエントリの列挙に関しては共用アクセス制御が効くので、
FindFirstFileだけNTFSやFATの機能のサブセットになっています。
引用返信 編集キー/
■20482 / inTopicNo.110)  Re[44]: ディレクトリの排他アクセス
□投稿者/ れい (645回)-(2008/06/11(Wed) 06:19:56)
No20480 (ネタ好き さん) に返信
> れいさんの言っている事は分かるのですが、やはり私が以前言った階層のロック問題を解決しない限り、開発者ユーザにAPIを開放するのは企業的に危険であるといっているのです。おまけにWindowsはAPIを抽象化し、「開発者に楽をさせる」方針を採っていますので、UNIX系OSのように薄い階層を持つ構造とは違って、開発者に何らかの意図的な手順を踏ませるわけです。
> WindowsOSがディレクトリとファイルを同一に扱うのは【効率】的であるからであって、APIとして公開する部分については【概念】を提供しているわけですから、ディレクトリとファイルの扱いに明確に一線を引いているのではないかと私は推測しています。 

なんかだんだん「歴史的理由」ではなく
ネタ好きさんの言う「わざと違うように見せてる」というのが正しい気がしてきました。
(ロックの粒度、パフォーマンスという件に関しては納得していないですが。)

> ディレクトリとファイルの扱いに明確に一線を引いているのではないかと私は推測しています。 

この理由をもう少し詳しく説明していただけませんか?
「異なるものである」というのを明確にすることで、
どんな利点があるのでしょうか?
引用返信 編集キー/
■20483 / inTopicNo.111)  Re[45]: ディレクトリの排他アクセス
□投稿者/ ネタ好き (427回)-(2008/06/11(Wed) 07:50:39)
2008/06/11(Wed) 07:51:41 編集(投稿者)

No20482 (れい さん) に返信
>この理由をもう少し詳しく説明していただけませんか?
「異なるものである」というのを明確にすることで、
どんな利点があるのでしょうか?

これはあくまで私の推測で、自身の好みの問題から言えばマイクソフトのやり方は気に入らない事を先に明らかにしておきます。
では早速本題に入ります。私が思うに概念を会社として提供するには、「どんな開発者でも分かりやすい考え方」を提供しなくてはならないと思います。そうしないと、概念を理解しない開発者のうっかりミスにより、エンドユーザーから苦情が殺到しその結果会社は倒産してしまうでしょう。
この分かりやすい概念と言うところが曲者で、「Windowsのファイルシステムはハードウェアを反映しておりますので、ファイルとディレクトリの区別はありません。見た目が違うだけです。」とマイクロソフトがいくら説明しても開発者から「でも、ファイルはファイルを含まないけど、ディレクトリはファイルを含むよ?これは何故?あれ?でもAPIは一緒じゃん????」と言われてしまうと思います。
ですから歴史的もマーケティング的にもマイクソフトは「ディレクトリとファイルは見た目が違います。ほら、フォルダがあって中にファイルがあるでしょ。ですからAPIも違います。」と言うしか無いのだと思います。
引用返信 編集キー/
■20484 / inTopicNo.112)  Re[46]: ディレクトリの排他アクセス
□投稿者/ NyaRuRu (45回)-(2008/06/11(Wed) 09:01:44)
今回の件とは直接関係ないかもしれませんが,/usr/src/linux/Documentation/filesystems/directory-locking とかおもしろいですね.

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=Documentation/filesystems/directory-locking;hb=HEAD
引用返信 編集キー/
■20492 / inTopicNo.113)  Re[47]: ディレクトリの排他アクセス
□投稿者/ れい (646回)-(2008/06/11(Wed) 10:15:51)
No20484 (NyaRuRu さん) に返信
> 今回の件とは直接関係ないかもしれませんが,/usr/src/linux/Documentation/filesystems/directory-locking とかおもしろいですね.

OS内部、ファイルシステムの話ですね。

WinDDKのsrc/filesys/fastfatを見ればわかりますが、
per-inodeのロックをFCBのロックに、
per-filesystemのロックをVCBのロックに対応付けると
大体同じような仕組みになってますよね。

ちょっと違うのはファイルの作成です。
Windowsでは作成時にはボリューム全体をロックしますが、
Linuxはinodeの存在が保証されてるのでディレクトリのロックで大丈夫。

そんな感じでWindowsの方がロックの粒度は荒い。
なのにFSのパフォーマンスはWindowsの方が一般に高いらしいですね。

NyaRuRuさんが示してくれた資料のような感じに
具体的に「デッドロックを防ぐため」とかいう理由があって、
理論的にFindFirstFileが良い実装である、見たいな資料があるといいんですが。

今のところ理由は3つ。

1 歴史的経緯
2 ロックの粒度
3 ディレクトリとファイルの違いをあえて意識させたい

もし本当なら3に一番思想が含まれるので一番重要だと思うのですが。
ネタ好きさんの話だけでは私にはちょっと納得いかないです。

設計者の小言とか、どこかに資料落ちてないかなぁ。
引用返信 編集キー/
■20501 / inTopicNo.114)  Re[48]: ディレクトリの排他アクセス
□投稿者/ ネタ好き (428回)-(2008/06/11(Wed) 11:21:55)
No20492 (れい さん) に返信
> もし本当なら3に一番思想が含まれるので一番重要だと思うのですが。
> ネタ好きさんの話だけでは私にはちょっと納得いかないです。

私もこの手の話題が好きだし勉強になるので最後まで付き合います。
私自身もこの件が気になっていたのですが、よく考えるとディレクトリはファイルを抱合できると言う点が違いますよね。そこがポイントかもしれません。

引用返信 編集キー/
■20514 / inTopicNo.115)  Re[43]: ディレクトリの排他アクセス
□投稿者/ す (38回)-(2008/06/11(Wed) 14:49:00)
2008/06/11(Wed) 17:03:40 編集(投稿者)

No20479 (れい さん) に返信
> ■No20477 (す さん) に返信
>>■No20476 (れい さん) に返信
> >>「c:\aaa」を開いてディレクトリ一覧を見て、そこから取得します。
>>というのは、
>>>>でも、「メタ情報」はディレクトリ側に持ってるんですよね?
>>ということで
>
> だから違います。
> 持っていません。
>
>>>>それを見るのにもファイルをオープンしないといけないんですか?
>>しなくてよいということではないのですか?
>
> 一部のメタ情報のみ、親のハンドルから見ることが出来ますが、
> 書き込めません。

findfirstfileで得られる情報はディレクトリにあると思ったのですが、
違うのですか?
不思議な作りですね。

追記
findfirstfileで列挙すると、ファイルを全部開いていくわけですか?
不思議な実装ですね。
引用返信 編集キー/
■20540 / inTopicNo.116)  Re[44]: ディレクトリの排他アクセス
□投稿者/ れい (647回)-(2008/06/12(Thu) 11:02:26)
No20514 (す さん) に返信
> findfirstfileで得られる情報はディレクトリにあると思ったのですが、
> 違うのですか?
> 不思議な作りですね。
>
> 追記
> findfirstfileで列挙すると、ファイルを全部開いていくわけですか?
> 不思議な実装ですね。

どこまでをディレクトリとみて何処までをディレクトリエントリとみるかで
答えは変わりますが。

FileSystem的には、エントリのメタ情報(ファイル属性や更新日時)などは
エントリを開かなければ変更できません。
エントリの親ディレクトリを開いても変更できません。

これはメタ情報が親ディレクトリに属するという思想ではなく、
エントリそのものに属するという思想です。

> 不思議な作りですね。

私には不思議ではありませんが。

> 追記
> findfirstfileで列挙すると、ファイルを全部開いていくわけですか?
> 不思議な実装ですね。

前にいったように。(何回も言わせないで)
FindFirstFileは親ディレクトリを開いて列挙します。
「一部のメタ情報」のみ、親ディレクトリのハンドルから列挙できます。
変更は出来ません。

その「一部のメタ情報」には、
明らかにファイルの実体に属すであろう「ファイルのサイズ」も含まれます。

別に不思議ではないですね。
引用返信 編集キー/
■20552 / inTopicNo.117)  Re[45]: ディレクトリの排他アクセス
□投稿者/ ネタ好き (434回)-(2008/06/12(Thu) 13:20:29)
2008/06/12(Thu) 13:21:12 編集(投稿者)

No20540 (れい さん) に返信
Windowsはまだi-node方式になっていなかったのか・・・
ディレクトリエントリに直接属性を持たせる構造になんか利点があるのかな・・・
れいさんはどう思われますか?

引用返信 編集キー/
■20555 / inTopicNo.118)  Re[46]: ディレクトリの排他アクセス
□投稿者/ れい (648回)-(2008/06/12(Thu) 13:56:02)
No20552 (ネタ好き さん) に返信
> 2008/06/12(Thu) 13:21:12 編集(投稿者)
>
> ■No20540 (れい さん) に返信
> Windowsはまだi-node方式になっていなかったのか・・・
> ディレクトリエントリに直接属性を持たせる構造になんか利点があるのかな・・・
> れいさんはどう思われますか?
>

なんか勘違いしてますねぇ

まず、まるでinode/vnodeの方がいいみたいな言い方になっていますが、
一概にそうとはいえません。逆も然り。
ちなみにWindowsではエントリそのものを示すのにFCBというのを使ってます。
生成・消滅あたりが微妙に違いますがinodeとほぼ同じです。

それと、実際にデータがどこに保存されているのかは話題にしてません。
どこに保存されてるように見えるのかを話題にしてます。

内部的にメタ情報が専用のテーブル保存されていてもかまいません。

とりあえず、Win32もファイルシステムも
エントリのメタ情報を取得・更新する際には
エントリをハンドルとして開かねばならないのです。
(例外はディレクトリ列挙における一部の情報の取得)

ということは、エントリのメタ情報はエントリに保持されてるとみなすのが妥当です。

その構造が私の疑問に大きく関わっているのなら、
ぜひ教えていただきたいですが。


引用返信 編集キー/
■20584 / inTopicNo.119)  Re[47]: ディレクトリの排他アクセス
□投稿者/ ネタ好き (436回)-(2008/06/12(Thu) 16:49:17)
No20555 (れい さん) に返信
マイクソフトが見せようとしている概念と何らかの係わり合いがある可能性があると思ったのが1点で、
Windowsそのような構造が何の利点があるのかと訊きたかったというのもあります。
私には利点が分からないんです。もし利点があるのならば、その利点と概念が何らかの形で結びついているかもしれないと考えたのです。
引用返信 編集キー/
■20597 / inTopicNo.120)  Re[48]: ディレクトリの排他アクセス
 
□投稿者/ れい (649回)-(2008/06/12(Thu) 17:42:51)
No20584 (ネタ好き さん) に返信
> ■No20555 (れい さん) に返信
> マイクソフトが見せようとしている概念と何らかの係わり合いがある可能性があると思ったのが1点で、
> Windowsそのような構造が何の利点があるのかと訊きたかったというのもあります。
> 私には利点が分からないんです。もし利点があるのならば、その利点と概念が何らかの形で結びついているかもしれないと考えたのです。

では、考えて見ます。

ディレクトリがエントリのメタ情報を持つというモデルだと
あるエントリのメタ情報を参照・変更する際に、
親ディレクトリ名とエントリ名、メタ情報名を指定するのですよね。

で、エントリ自身がメタ情報を持つモデルだと
エントリ名とメタ情報名を指定すればいい。

後者の方がシンプルですね。

私の勘では、
メタ情報の種類が少ない場合は、前者の方がいい。
でも、メタ情報が多いなら後者がいいと思います。

あと、前者は「ルートディレクトリ」のメタ情報の保持場所で困ります。
あんまり使われてないですが、ルートディレクトリにもメタ情報がありますよね。

で、前者の場合はFindFirstFileも自然な気がします。
実際には後者なので、FindFirstFileは私には不自然です。

やっぱり歴史的理由かしら。

他のOSなどを知れば知るほど、WinAPIの癖が気になります。
特に列挙系が私は好きでは無いようです。
EnumXXXとか。FindFirstXXXとか。

そうそう。
FindFirstXXXの利点を一つ見つけました。
ディレクトリハンドルを開いて列挙指示するよりも、
ユーザー/カーネル切替が1回減ります。
引用返信 編集キー/

<前の20件 | 次の20件>
トピック内ページ移動 / << 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 >>

管理者用

- Child Tree -