File tree Expand file tree Collapse file tree 3 files changed +116
-0
lines changed
examples/singleapp/mkfifo/read Expand file tree Collapse file tree 3 files changed +116
-0
lines changed Original file line number Diff line number Diff line change 1+ tmp-fifo
2+ app
Original file line number Diff line number Diff line change 1+ # https://taskfile.dev
2+
3+ version : ' 3'
4+
5+ vars :
6+ FIFO_FILE : ./tmp-fifo
7+
8+ tasks :
9+ default :
10+ cmds :
11+ - task : build
12+ - task : create-fifo
13+ - task : run
14+ build :
15+ cmds :
16+ - go build -o app .
17+ create-fifo :
18+ cmds :
19+ - rm -f {{.FIFO_FILE}}
20+ - mkfifo {{.FIFO_FILE}} -m0666
21+ run :
22+ cmds :
23+ # ワザと書込みを遅延させて実行
24+ - (sleep 3; echo "helloworld" > {{.FIFO_FILE}}) &
25+ - ./app -fname {{.FIFO_FILE}}
Original file line number Diff line number Diff line change 1+ //go:build linux
2+
3+ package main
4+
5+ import (
6+ "bufio"
7+ "flag"
8+ "log"
9+ "os"
10+ "time"
11+ )
12+
13+ var (
14+ fname string
15+ )
16+
17+ func init () {
18+ log .SetFlags (log .Lmicroseconds )
19+
20+ flag .StringVar (& fname , "fname" , "" , "FIFO file name" )
21+ flag .Parse ()
22+ }
23+
24+ func main () {
25+ if err := run (); err != nil {
26+ log .Fatal (err )
27+ }
28+ }
29+
30+ func run () error {
31+ //
32+ // 名前付きパイプを開く
33+ // os.OpenFile() にて、モード指定で os.ModeNamedPipe を指定する
34+ // os.O_RDOONLYで開くと読み取り専用となるが、この場合書込みが発生するまで
35+ // ブロックされる。これはUNIXの名前付きパイプの挙動に従った動作である。
36+ //
37+ var (
38+ f * os.File
39+ err error
40+ )
41+
42+ log .Println ("[Before] os.OpenFile(os.O_RDOONLY)" )
43+
44+ // 対象となる名前付きパイプに書込みが発生していない場合、ここでブロックされる。
45+ f , err = os .OpenFile (fname , os .O_RDONLY , os .ModeNamedPipe )
46+ if err != nil {
47+ return err
48+ }
49+ defer f .Close ()
50+
51+ log .Println ("[After ] os.OpenFile(os.O_RDOONLY)" )
52+
53+ //
54+ // データを読み取り
55+ //
56+ type (
57+ data struct {
58+ value string
59+ err error
60+ }
61+ )
62+ var (
63+ reader = bufio .NewReader (f )
64+ lines = make (chan data )
65+ timeout = time .Second
66+ )
67+
68+ go func () {
69+ line , err := reader .ReadString ('\n' )
70+ lines <- data {line , err }
71+ }()
72+
73+ select {
74+ case line := <- lines :
75+ if line .err != nil {
76+ return line .err
77+ }
78+
79+ log .Println (line .value )
80+ case <- time .After (timeout ):
81+ // 上記で記載した通り、os.O_RDOONLYのみで開いている場合
82+ // ブロッキングモードとなっているため、os.OpenFile()の呼び出しの
83+ // 時点でブロックされることとなる。つまり、実際にデータを読み出す
84+ // タイミングでは待たされることが無いため、このタイムアウトは通らない。
85+ log .Println ("timeout" )
86+ }
87+
88+ return nil
89+ }
You can’t perform that action at this time.
0 commit comments