Swiftで fork(2)
を使おうとすると、以下のようにコンパイルエラーになります。
error: 'fork()' is unavailable: Please use threads or posix_spawn*()
これはCocoaフレームワークがfork-safeでないからのようです。これ自体は自分の脚をうっかり撃たなくていい仕組みで歓迎しますが、危険を承知で fork(2)
を使いたいこともあります。そんなとき、 @asmname
でCの関数をSwiftにマッピングすることができます。これで自分の脚も撃ち放題ですね。
#!/usr/bin/xcrun swift
import Darwin
// `let pid = fork()` はコンパイルエラーになるのでシンボルを直接参照する
@asmname("fork")
func myFork() -> pid_t
let pid = myFork()
if pid != 0 {
waitpid(pid, nil, 0)
println("Hi. I am the parent.")
exit(0)
} else {
sleep(1)
println("Hi, I am a child.")
exit(0)
}
$ ./fork.swift
Hi, I am a child.
Hi. I am the parent.
なお fork(2)
の注意点やプロセスのdaemon化については TN2083 Daemons and Agentsにまとまっています。