Skip to content

Commit 708bec0

Browse files
authored
Merge pull request #817 from devlights/add-mkfifo-write-example
2 parents 59ad607 + 97c9af8 commit 708bec0

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tmp-fifo
2+
app
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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+
- ./app -fname {{.FIFO_FILE}} &
24+
- (sleep 2; (date '+%H:%M:%S.%6N'; cat {{.FIFO_FILE}}) | xargs)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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_WRONLY)")
43+
44+
// 対象となる名前付きパイプに読み込みが発生していない場合、ここでブロックされる。
45+
f, err = os.OpenFile(fname, os.O_WRONLY, os.ModeNamedPipe)
46+
if err != nil {
47+
return err
48+
}
49+
defer f.Close()
50+
51+
log.Println("[After ] os.OpenFile(os.O_WRONLY)")
52+
53+
//
54+
// データを書込み
55+
//
56+
type (
57+
data struct {
58+
numWrites int
59+
err error
60+
}
61+
)
62+
var (
63+
writer = bufio.NewWriter(f)
64+
results = make(chan data)
65+
timeout = time.Second
66+
)
67+
68+
go func() {
69+
n, err := writer.WriteString("helloworld\n")
70+
if err == nil {
71+
err = writer.Flush()
72+
}
73+
74+
results <- data{n, err}
75+
}()
76+
77+
select {
78+
case r := <-results:
79+
if r.err != nil {
80+
return r.err
81+
}
82+
83+
log.Printf("Write %d byte(s)", r.numWrites)
84+
case <-time.After(timeout):
85+
// 上記で記載した通り、os.O_WRONLYのみで開いている場合
86+
// ブロッキングモードとなっているため、os.OpenFile()の呼び出しの
87+
// 時点でブロックされることとなる。つまり、実際にデータを書き出す
88+
// タイミングでは待たされることが無いため、このタイムアウトは通らない。
89+
log.Println("timeout")
90+
}
91+
92+
return nil
93+
}

0 commit comments

Comments
 (0)