---
# System prepended metadata

title: 第11回 ファイルシステムと、その上のGo言語の関数たち（2）
tags: [Goならわかるシステムプログラミング]

---

###### tags: `Goならわかるシステムプログラミング`

# 第11回 ファイルシステムと、その上のGo言語の関数たち（2）
https://ascii.jp/elem/000/001/430/1430904/

## 1. ファイルパスとマルチプラットフォーム
* ファイルパスでファイルを指定する．
* OS間におけるパスの表記方法の違いは，Goではpath/filepathパッケージで吸収できる．

## 2. path/filepathパッケージの関数たち
* filepath.Join(): パスとファイル名とを連結．
* filepath.Split(): パスからファイル名とその親ディレクトリに分割．
他にも，パスの欲しい部分を分割して返す関数がある．
* filepath.SplitList(): 複数パスの文字列を個別パスのリストに変換．
whichの実装ができる．
* filepath.Clean(): パスの表記整形．Abs(),Rel()で絶対パスや相対パスも出せる．
* 環境変数や~(チルダ)を含んだパスの展開はosパッケージまで降りる．
* filepath.Match()，filepath.Glob(): ファイルのパターンマッチング．
* filepath.Walk(): 指定パスから深さ優先でトラバースし，その都度関数を呼び出す．
トラバース: ディレクトリのような木構造をすべてたどること．

コールバック関数

## 3. ファイルの変更監視（syscall.Inotify*）
ファイルの変更を監視し自動で処理を行うことができる．
* 指定ファイルの変更検知(パッシブ)
* os.Statなどによる定期的なフォルダ走査(アクティブ)

Goでは，gopkg.in/fsnotify.v1 パッケージ利用したパッシブな方法など．


# 第12回 ファイルシステムと、その上のGo言語の関数たち（3）
https://ascii.jp/elem/000/001/440/1440099/

## 1. ファイルのロック（syscall.Flock()）
複数のプロセス間で同じリソースを同時に変更しないようにする.

ファイルロックの方法
* ロックファイル
* システムコールでファイル自体をロック

後者は，通常のファイル入出力では確認されず，上書きされうる．
強制力のないロック → アドバイザリーロック(勧告ロック)という．
(Windowsでは強制ロックのみ)

* syscall.Flock()によるPOSIX系OSでのファイルロック
共有ロック：複数のプロセスから同じリソースに対して同時にかけられる．読み込みなどに
排他ロック：他のプロセスからの共有ロックをブロック．書き込みなどに

syscall.Flock()では，他のロックが外れるまで待たされる．
→ ノンブロッキングモード(あとで)

GoのBuild Constraints：コード先頭のコメントでビルドの挙動を変える．

## 2. ファイルのメモリへのマッピング（syscall.Mmap）
ランダムアクセス：ファイルの特定のバイト位置を指定するアクセス
シーケンシャルアクセス：ファイルを先頭から順番に読み込んでいくアクセス

syscall.Mmap()システムコールで，ファイルの中身をそのままメモリ上に展開できる．
ラップした github.com/edsrzf/mmap-go パッケージ

## 3. 同期・非同期 / ブロッキング・ノンブロッキング

* 同期: データ処理の入出力が可能になった時点で通知．
* 非同期: データ処理の入出力が完了した時点で通知．
* ブロッキング: データ処理が完了するまで待つ．
* ノンブロッキング: データ処理が完了するまで待たない．
<img src="https://i.imgur.com/v6w2Esf.jpg" width=50%>
* 同期・ブロッキング：処理を投げ，完了するまで何もせずに待つ．
* 同期・ノンブロッキング：一定間隔で要求がないか尋ねる．
* 非同期・ブロッキング：I/O多重化．
* 非同期・ノンブロッキング：メインとは別のスレッドで処理を行い，通知だけ受け取る．
<img src="https://i.imgur.com/ESJixxZ.jpg" width=55%>
<img src="https://i.imgur.com/j1Sej9b.jpg" width=55%>

\
\
上はちょっと特殊な定義の仕方な気がする．以下はメモ．

* 同期: IO操作が終わるまでブロックする．
* 非同期: IO操作を発効したスレッドがブロックせずに別の処理を行える．
　　　　コールバック関数で通知が来る．
* ブロッキング: IO操作する前に待ちが発生する性質．
* ノンブロッキング: IO操作する前に待ちが発生する場合関数から返る性質．
* IO多重化: 複数のfdに対して監視を行ない，ブロックせずに操作可能なfdを通知する仕組み．


## 4. select属のシステムコールによるI/O多重化

1スレッドでたくさんの入出力を効率よく扱う非同期・ブロッキング
→ I/O多重化 → select属 API

select関数:
複数のイベントのいずれかが発生するまで待ち，１つ以上のイベントが発生した場合，あるいは指定した時間が経過した場合にプロセスに起こすようにカーネルに指示できる．

Goでの実装
./testフォルダ内の変更を監視する非同期・ブロッキングのイベント待ち処理．