Rustã§ããã»ã¹ãä½ããããªã£ãã®ã§è©¦ãããå¤ãªã¨ããããã°æãã¦ãã ããã
Rust ã§ã·ã¹ãã å¨ãã®ããã°ã©ãã³ã°ãããå ´åãnixã¨ããã¯ã¬ã¼ãã便å©ãã·ã¹ãã ã³ã¼ã«å¼ã³åºãã Result<T, E>
ã§è¿ãã¦ãããããã«ãªã£ã¦ã極ãã¦æ±ãããããªãã
ããã»ã¹å¨ãã«ã¤ãã¦ã¯ã fork(2)
㨠wait(2)/waitpid(2)
ã®ã©ããã¼ãåå¨ããã®ã§ã¾ãã¯ç´ ç´ã«ä½¿ãã
åç´ãªä¾
use nix::sys::wait::waitpid; use nix::unistd::{fork, ForkResult}; use std::thread::sleep; use std::time::Duration; fn main() -> Result<(), Box<dyn std::error::Error>> { println!("Hello, world!"); match unsafe { fork()? } { ForkResult::Parent { child } => { println!("Child Pid: {}", child); let status = waitpid(child, None)?; println!("Reaped: {:?}", status); } ForkResult::Child => { println!("I'm a new child process"); sleep(Duration::from_secs(5)); println!("Exit!!1"); } } Ok(()) }
fork()
ã¯nixä¸ã§ã unsafe ã§ãããè¿ãå¤ã¯ Result ã§å
ã¾ãã ForkResult
ã¨ããenumããããæ¯ãåãããã¨ã§è¦ªåããã»ã¹ã®å¤å®ãã§ããã
ä¸è¨ã®ã³ã¼ããLinuxä¸ã§åããã¨ãããã«ããããããã»ã¹ããªã¼ãä½æãããã
vagrant 14661 4.7 0.0 3132 860 pts/0 S+ 10:38 0:00 | \_ target/debug/fork-wait-example vagrant 14663 0.0 0.0 3132 132 pts/0 S+ 10:38 0:00 | \_ target/debug/fork-wait-example
æ£å¸¸çµäºæã«ã¯ããã
Hello, world! Child Pid: 15207 I'm a new child process Exit!!1 Reaped: Exited(Pid(15207), 0)
ã·ã°ãã«ã§åããã»ã¹ãkillããã¨ããããæãããªã waitpid
ã®è¿ãå¤ãenumã§ããã第2å¼æ°ã§ã¯ã WNOHANG
ãªã© man waitpid ã«ãããªãã·ã§ã³ãåãä»ãã模æ§ã
Hello, world! Child Pid: 15224 I'm a new child process Reaped: Signaled(Pid(15224), SIGTERM, false)
è¤æ°ã¯ã¼ã«ãä½ã
ã¯ã¼ã«ãä½ãå ´åã¯åç´ã« fork()
ãå¼ãã§ã waitpid(None, None)
ã§å¾
ã¡åããã°OKããªãã nix::wait::wait
ã¨ããã·ã§ã¼ãã«ãããããã
use nix::sys::wait::waitpid; use nix::unistd::{fork, ForkResult}; use std::thread::sleep; use std::time::Duration; fn main() -> Result<(), Box<dyn std::error::Error>> { println!("Hello, world!"); for _ in 0..5 { match unsafe { fork()? } { ForkResult::Parent { child } => { println!("Added child. Pid: {}", child); } ForkResult::Child => { println!("I'm a new child process"); sleep(Duration::from_secs(30)); println!("Exit!!1"); std::process::exit(0) } } sleep(Duration::from_secs(3)) } while let Ok(status) = waitpid(None, None) { println!("Reaped child. Status: {:?}", status); } Ok(()) }
èµ°ãããã¨ããã
vagrant 15761 1.2 0.0 3132 1752 pts/0 S+ 10:59 0:00 | \_ target/debug/fork-wait-example vagrant 15763 0.0 0.0 3132 136 pts/0 S+ 10:59 0:00 | \_ target/debug/fork-wait-example vagrant 15768 0.0 0.0 3132 136 pts/0 S+ 10:59 0:00 | \_ target/debug/fork-wait-example vagrant 15771 0.0 0.0 3132 136 pts/0 S+ 10:59 0:00 | \_ target/debug/fork-wait-example vagrant 15774 0.0 0.0 3132 136 pts/0 S+ 10:59 0:00 | \_ target/debug/fork-wait-example vagrant 15778 0.0 0.0 3132 136 pts/0 S+ 10:59 0:00 | \_ target/debug/fork-wait-example
ä¸ã¤ä¸ã¤ã®çµäºã¹ãã¼ã¿ã¹ã確èªã§ãããwhile let ã®ã«ã¼ãã§æ±ããå¯è½ã«ãªãã極ãã¦ä¾¿å©ã
Hello, world! I'm a new child process Added child. Pid: 15763 Added child. Pid: 15768 I'm a new child process Added child. Pid: 15771 I'm a new child process Added child. Pid: 15774 I'm a new child process Added child. Pid: 15778 I'm a new child process Exit!!1 Reaped child. Status: Exited(Pid(15763), 0) Exit!!1 Reaped child. Status: Exited(Pid(15768), 0) Exit!!1 Reaped child. Status: Exited(Pid(15771), 0) Exit!!1 Reaped child. Status: Exited(Pid(15774), 0) Exit!!1 Reaped child. Status: Exited(Pid(15778), 0)
forkã®çæç¹
ãã«ãã¹ã¬ããã®å ´åãåããã»ã¹ã«ããã¦ã¯ async-signal-safe ãªé¢æ°ã®ã¿ãå¼ã³åºãã¹ãã¨ãã¦ãã ããªã®ã§ãä»åã®ãµã³ãã«ããã°ã©ã ã®ããã«è¦ªåå
±ã·ã³ã°ã«ã¹ã¬ãããªãæ°ã«ããªãã¦ãããã¨ã¯æã*1ãããã¼ã¢ã³ãæ¸ããããªå ´åãã«ãã¹ã¬ããã®ã©ã¤ãã©ãªãå
é¨ã§ä½¿ããã¨ããããããåºæ¬çã«ã¯å³åº§ã« execve()
ãããããªç®çãè¯ããããããªããä¾ãã°èªåèªèº«ã execve
ã㦠$0
ã§åä½ãå¤ãããããªãã¿ã¼ã³ã¯è¯ãããã
ç¹ã«ãæ¸ãã¦ããéã memory allocation may not be async-signal-safe
ãªã®ã§ãè¤éãªæ§é ä½ãçæããããã¹ãã§ã¯ãªãã ããã
ä»åº¦ã¯ãããã»ã¹ééä¿¡ã試ãã socketpair ã¨ãã
*1:psã®STATãããããã