wait(2) - wariua/manpages-ko GitHub Wiki

NAME

wait, waitpid, waitid - ν”„λ‘œμ„ΈμŠ€ μƒνƒœ λ³€κ²½ 기닀리기

SYNOPSIS

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *wstatus);

pid_t waitpid(pid_t pid, int *wstatus, int options);

int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
                /* glibc 및 POSIX의 μΈν„°νŽ˜μ΄μŠ€. 기반 μ‹œμŠ€ν…œ
                   ν˜ΈμΆœμ— λŒ€ν•œ μ •λ³΄λŠ” NOTES μ°Έκ³ . */

glibc κΈ°λŠ₯ 확인 맀크둜 μš”κ±΄ (feature_test_macros(7) μ°Έκ³ ):

waitid():
glibc 2.26λΆ€ν„°:
_XOPEN_SOURCE >= 500 ||
_POSIX_C_SOURCE >= 200809L
glibc 2.25 및 이전:
_XOPEN_SOURCE
|| /* glibc 2.12λΆ€ν„°: */ _POSIX_C_SOURCE >= 200809L
|| /* glibc 버전 <= 2.19: */ _BSD_SOURCE

DESCRIPTION

이 μ‹œμŠ€ν…œ ν˜ΈμΆœλ“€μ€ λͺ¨λ‘ 호좜 ν”„λ‘œμ„ΈμŠ€μ˜ μžμ‹μ—μ„œμ˜ μƒνƒœ 변경을 기닀리고 μƒνƒœκ°€ 바뀐 μžμ‹μ— λŒ€ν•œ 정보λ₯Ό μ–»λŠ” 데 μ‚¬μš©ν•˜λŠ” 것이닀. μžμ‹μ΄ μ’…λ£Œν•˜λŠ” 것, μžμ‹μ΄ μ‹œκ·Έλ„μ— μ˜ν•΄ μ€‘μ§€λ˜λŠ” 것, μžμ‹μ΄ μ‹œκ·Έλ„μ— μ˜ν•΄ μž¬κ°œλ˜λŠ” 것을 μƒνƒœ λ³€κ²½μœΌλ‘œ λ³Έλ‹€. μžμ‹μ΄ μ’…λ£Œν•˜λŠ” κ²½μš°μ— wait을 μˆ˜ν–‰ν•˜λ©΄ μ‹œμŠ€ν…œμ΄ μžμ‹κ³Ό μ—°κ΄€λœ μžμ›λ“€μ„ ν•΄μ œν•  수 있게 λœλ‹€. wait을 μˆ˜ν–‰ν•˜μ§€ μ•ŠμœΌλ©΄ μ’…λ£Œν•œ μžμ‹μ΄ "μ’€λΉ„" μƒνƒœλ‘œ λ‚¨λŠ”λ‹€. (μ•„λž˜ NOTES μ°Έκ³ .)

μžμ‹μ΄ 이미 μƒνƒœλ₯Ό λ°”κΎΈμ—ˆμœΌλ©΄ 이 ν˜ΈμΆœλ“€μ΄ μ¦‰μ‹œ λ°˜ν™˜ν•œλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ μžμ‹μ΄ μƒνƒœλ₯Ό λ°”κΎΈκ±°λ‚˜ μ‹œκ·Έλ„ ν•Έλ“€λŸ¬κ°€ ν˜ΈμΆœμ„ μ€‘λ‹¨μ‹œν‚¬ λ•ŒκΉŒμ§€ (sigaction(2)의 SA_RESTART ν”Œλž˜κ·Έλ‘œ μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ μžλ™ μž¬μ‹œμž‘ν•˜μ§€ μ•ŠλŠ”λ‹€κ³  κ°€μ •) 블둝 ν•œλ‹€. 이 νŽ˜μ΄μ§€ λ‚˜λ¨Έμ§€μ—μ„œλŠ” μƒνƒœκ°€ λ°”λ€Œμ—ˆμ§€λ§Œ 아직 이 μ‹œμŠ€ν…œ ν˜ΈμΆœλ“€ 쀑 ν•˜λ‚˜λ‘œ 기닀리지 μ•Šμ€ μžμ‹μ„ 기닀릴 수 μžˆλ‹€(waitable)κ³  ν‘œν˜„ν•œλ‹€.

wait()κ³Ό waitpid()

wait() μ‹œμŠ€ν…œ ν˜ΈμΆœμ€ μžμ‹λ“€ 쀑 ν•˜λ‚˜κ°€ μ’…λ£Œν•  λ•ŒκΉŒμ§€ 호좜 μŠ€λ ˆλ“œμ˜ 싀행을 μ€‘μ§€ν•œλ‹€. wait(&wstatus) ν˜ΈμΆœμ€ λ‹€μŒκ³Ό λ™λ“±ν•˜λ‹€.

waitpid(-1, &wstatus, 0);

waitpid() μ‹œμŠ€ν…œ ν˜ΈμΆœμ€ pid 인자둜 μ§€μ •ν•œ μžμ‹μ΄ μƒνƒœλ₯Ό λ°”κΏ€ λ•ŒκΉŒμ§€ 호좜 μŠ€λ ˆλ“œμ˜ 싀행을 μ€‘μ§€ν•œλ‹€. 기본적으둜 waitpid()λŠ” μžμ‹ μ’…λ£Œλ§Œ κΈ°λ‹€λ¦¬μ§€λ§Œ μ•„λž˜μ—μ„œ μ„€λͺ…ν•˜λ“― options 인자λ₯Ό 톡해 λ™μž‘ 방식을 λ³€κ²½ν•  수 μžˆλ‹€.

pid의 값은 λ‹€μŒμΌ 수 μžˆλ‹€.

< -1
ν”„λ‘œμ„ΈμŠ€ κ·Έλ£Ή IDκ°€ pid의 μ ˆλŒ“κ°’κ³Ό 같은 아무 μžμ‹ ν”„λ‘œμ„ΈμŠ€λ‚˜ 기닀리기
-1
아무 μžμ‹ ν”„λ‘œμ„ΈμŠ€λ‚˜ 기닀리기
0
ν”„λ‘œμ„ΈμŠ€ κ·Έλ£Ή IDκ°€ 호좜 ν”„λ‘œμ„ΈμŠ€μ˜ ν”„λ‘œμ„ΈμŠ€ κ·Έλ£Ή ID와 같은 아무 μžμ‹ ν”„λ‘œμ„ΈμŠ€λ‚˜ 기닀리기
> 0
ν”„λ‘œμ„ΈμŠ€ IDκ°€ pid κ°’κ³Ό 같은 μžμ‹ 기닀리기

options의 값은 λ‹€μŒ μƒμˆ˜λ“€μ„ 0개 λ˜λŠ” κ·Έ 이상 OR ν•œ 것이닀.

WNOHANG
μ’…λ£Œν•œ μžμ‹μ΄ μ—†μœΌλ©΄ μ¦‰μ‹œ λ°˜ν™˜ν•œλ‹€.
WUNTRACED
μžμ‹μ΄ μ •μ§€ν•œ (ν•˜μ§€λ§Œ ptrace(2) 좔적 λŒ€μƒμ€ μ•„λ‹Œ) κ²½μš°μ—λ„ λ°˜ν™˜ν•œλ‹€. μ •μ§€ν–ˆμœΌλ©΄μ„œ 좔적 λŒ€μƒμΈ μžμ‹μ˜ μƒνƒœλŠ” 이 μ˜΅μ…˜μ„ μ§€μ •ν•˜μ§€ μ•Šμ•„λ„ μ œκ³΅λœλ‹€.
WCONTINUED (λ¦¬λˆ…μŠ€ 2.6.10λΆ€ν„°)
μ •μ§€ν–ˆλ˜ μžμ‹μ΄ SIGCONT μ „λ‹¬λ‘œ 재개된 κ²½μš°μ—λ„ λ°˜ν™˜ν•œλ‹€.

(λ¦¬λˆ…μŠ€ μ „μš© μ˜΅μ…˜λ“€μ— λŒ€ν•΄μ„  μ•„λž˜ μ°Έκ³ .)

wstatusκ°€ NULL이 μ•„λ‹ˆλ©΄ wait()κ³Ό waitpid()κ°€ κ·Έ int에 μƒνƒœ 정보λ₯Ό μ €μž₯ν•΄ μ€€λ‹€. λ‹€μŒ λ§€ν¬λ‘œλ“€λ‘œ κ·Έ μ •μˆ˜λ₯Ό 쑰사할 수 μžˆλ‹€. (wait()κ³Ό waitpid()μ—μ„œμ²˜λŸΌ μ •μˆ˜ 포인터λ₯Ό λ°›λŠ” 게 μ•„λ‹ˆλΌ μ •μˆ˜ 자체λ₯Ό 인자둜 λ°›λŠ”λ‹€!)

WIFEXITED(wstatus)
μžμ‹μ΄ μ •μƒμ μœΌλ‘œ, 즉 exit(3)λ‚˜ _exit(2)λ₯Ό ν˜ΈμΆœν•˜κ±°λ‚˜ main()μ—μ„œ λ°˜ν™˜ν•˜μ—¬ μ’…λ£Œν–ˆμœΌλ©΄ 참을 λ°˜ν™˜ν•œλ‹€.
WEXITSTATUS(wstatus)
μžμ‹μ˜ μ’…λ£Œ μƒνƒœλ₯Ό λ°˜ν™˜ν•œλ‹€. 이 값은 μžμ‹μ΄ exit(3)λ‚˜ _exit(2) ν˜ΈμΆœμ— μ§€μ •ν•œ status μΈμžλ‚˜ main()의 return 문에 μ§€μ •ν•œ 인자의 ν•˜μœ„ 8λΉ„νŠΈμ΄λ‹€. 이 λ§€ν¬λ‘œλŠ” WIFEXITEDκ°€ 참을 λ°˜ν™˜ν–ˆμ„ λ•Œλ§Œ 써야 ν•œλ‹€.
WIFSIGNALED(wstatus)
μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ μ‹œκ·Έλ„λ‘œ μ’…λ£Œλ˜μ—ˆμœΌλ©΄ 참을 λ°˜ν™˜ν•œλ‹€.
WTERMSIG(wstatus)
μžμ‹ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ’…λ£Œμ‹œν‚¨ μ‹œκ·Έλ„μ˜ 번호λ₯Ό λ°˜ν™˜ν•œλ‹€. 이 λ§€ν¬λ‘œλŠ” WIFSIGNALEDκ°€ 참을 λ°˜ν™˜ν–ˆμ„ λ•Œλ§Œ 써야 ν•œλ‹€.
WCOREDUMP(wstatus)

μžμ‹μ΄ μ½”μ–΄ 덀프λ₯Ό λ§Œλ“€μ—ˆμœΌλ©΄ 참을 λ°˜ν™˜ν•œλ‹€. (core(5) μ°Έκ³ .) 이 λ§€ν¬λ‘œλŠ” WIFSIGNALEDκ°€ 참을 λ°˜ν™˜ν–ˆμ„ λ•Œλ§Œ 써야 ν•œλ‹€.

이 λ§€ν¬λ‘œλŠ” POSIX.1-2001에 λͺ…μ„Έλ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ©° μ–΄λ–€ μœ λ‹‰μŠ€ κ΅¬ν˜„(κ°€λ Ή AIX, SunOS)μ—μ„œλŠ” μ‚¬μš© κ°€λŠ₯ν•˜μ§€ μ•Šλ‹€. κ·ΈλŸ¬λ‹ˆ #ifdef WCOREDUMP ... #endif둜 κ°μ‹Έμ„œ μ‚¬μš©ν•˜λΌ.

WIFSTOPPED(wstatus)
μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ μ‹œκ·Έλ„ μ „λ‹¬λ‘œ 인해 μ •μ§€λ˜μ—ˆμœΌλ©΄ 참을 λ°˜ν™˜ν•œλ‹€. WUNTRACEDλ₯Ό μ¨μ„œ ν˜ΈμΆœν–ˆκ±°λ‚˜ μžμ‹μ„ 좔적 쀑인 경우(ptrace(2) μ°Έκ³ )μ—λ§Œ κ°€λŠ₯ν•˜λ‹€.
WSTOPSIG(wstatus)
μžμ‹μ΄ μ •μ§€ν•˜κ²Œ λ§Œλ“  μ‹œκ·Έλ„μ˜ 번호λ₯Ό λ°˜ν™˜ν•œλ‹€. 이 λ§€ν¬λ‘œλŠ” WIFSTOPPEDκ°€ 참을 λ°˜ν™˜ν–ˆμ„ λ•Œλ§Œ 써야 ν•œλ‹€.
WIFCONTINUED(wstatus)
(λ¦¬λˆ…μŠ€ 2.6.10λΆ€ν„°) μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ SIGCONT μ „λ‹¬λ‘œ 인해 μž¬κ°œλ˜μ—ˆμœΌλ©΄ 참을 λ°˜ν™˜ν•œλ‹€.

waitid()

(λ¦¬λˆ…μŠ€ 2.6.9λΆ€ν„° μ‚¬μš© κ°€λŠ₯ν•œ) waitid() μ‹œμŠ€ν…œ ν˜ΈμΆœμ—μ„œλŠ” μ–΄λ–€ μžμ‹ μƒνƒœ 변경을 기닀릴지에 λŒ€ν•΄ 더 μ •λ°€ν•œ μ œμ–΄κ°€ κ°€λŠ₯ν•˜λ‹€.

idtype 및 id 인자둜 λ‹€μŒκ³Ό 같이 기닀릴 μžμ‹(λ“€)을 μ„ νƒν•œλ‹€.

idtype == P_PID
ν”„λ‘œμ„ΈμŠ€ IDκ°€ id와 μΌμΉ˜ν•˜λŠ” μžμ‹ 기닀리기.
idtype == P_PGID
ν”„λ‘œμ„ΈμŠ€ κ·Έλ£Ή IDκ°€ id와 μΌμΉ˜ν•˜λŠ” 아무 μžμ‹μ΄λ‚˜ 기닀리기.
idtype == P_ALL
아무 μžμ‹μ΄λ‚˜ 기닀리기. idλŠ” λ¬΄μ‹œ.

optionsμ—μ„œ λ‹€μŒ ν”Œλž˜κ·Έλ“€μ„ ν•˜λ‚˜ 이상 OR ν•˜μ—¬ 기닀릴 μžμ‹ μƒνƒœ λ³€κ²½ μ’…λ₯˜λ₯Ό μ§€μ •ν•œλ‹€.

WEXITED
μ’…λ£Œν•œ μžμ‹μ„ κΈ°λ‹€λ¦°λ‹€.
WSTOPPED
μ‹œκ·Έλ„ μ „λ‹¬λ‘œ μ •μ§€λœ μžμ‹μ„ κΈ°λ‹€λ¦°λ‹€.
WCONTINUED
(μ•žμ„œ μ •μ§€λ˜μ—ˆλ‹€κ°€) SIGCONT μ „λ‹¬λ‘œ 재개된 μžμ‹μ„ κΈ°λ‹€λ¦°λ‹€.

optionsμ—μ„œ μΆ”κ°€λ‘œ λ‹€μŒ ν”Œλž˜κ·Έλ“€μ„ OR ν•  수 μžˆλ‹€.

WNOHANG
waitpid()μ—μ„œμ™€ κ°™μŒ.
WNOWAIT
μžμ‹μ„ 기닀릴 수 μžˆλŠ” μƒνƒœλ‘œ 남겨둔닀. 이후에 wait ν˜ΈμΆœμ„ λ‹€μ‹œ μ‚¬μš©ν•΄ μžμ‹ μƒνƒœ 정보λ₯Ό μ–»μ–΄μ˜¬ 수 μžˆλ‹€.

성곡 λ°˜ν™˜ μ‹œ waitid()λŠ” infopκ°€ κ°€λ¦¬ν‚€λŠ” siginfo_t ꡬ쑰체의 λ‹€μŒ ν•„λ“œλ“€μ„ μ±„μš΄λ‹€.

si_pid
μžμ‹μ˜ ν”„λ‘œμ„ΈμŠ€ ID.
si_uid
μžμ‹μ˜ μ‹€μ œ μ‚¬μš©μž ID. (λ‹€λ₯Έ κ΅¬ν˜„λ“€μ—μ„œλŠ” λŒ€λΆ€λΆ„ 이 ν•„λ“œλ₯Ό μ„€μ •ν•˜μ§€ μ•ŠλŠ”λ‹€.)
si_signo
항상 SIGCHLD둜 μ„€μ •.
si_status
μžμ‹μ΄ _exit(2)에 (λ˜λŠ” exit(3)에) μ€€ μ’…λ£Œ μƒνƒœ, λ˜λŠ” μžμ‹μ„ μ’…λ£Œμ‹œν‚€κ±°λ‚˜ μ •μ§€ν•˜κ±°λ‚˜ μž¬κ°œν•œ μ‹œκ·Έλ„. 이 ν•„λ“œλ₯Ό μ–΄λ–»κ²Œ 해석해야 ν•˜λŠ”μ§€λ₯Ό si_code ν•„λ“œλ‘œ νŒλ‹¨ν•  수 μžˆλ‹€.
si_code
λ‹€μŒ 쀑 ν•˜λ‚˜λ‘œ μ„€μ •: CLD_EXITED (μžμ‹μ΄ _exit(2)λ₯Ό ν˜ΈμΆœν–ˆμŒ), CLD_KILLED (μžμ‹μ΄ μ‹œκ·Έλ„λ‘œ μ£½μ—ˆμŒ), CLD_DUMPED (μžμ‹μ΄ μ‹œκ·Έλ„λ‘œ μ£½μ—ˆκ³  μ½”μ–΄λ₯Ό 덀프 ν–ˆμŒ), CLD_STOPPED (μžμ‹μ΄ μ‹œκ·Έλ„λ‘œ μ€‘μ§€λμŒ), CLD_TRAPPED (μΆ”μ ν•˜λŠ” μžμ‹μ΄ νŠΈλž©μ— 걸렸음), CLD_CONTINUED (μžμ‹μ΄ SIGCONT둜 재개됐음).

options에 WNOHANG을 μ§€μ •ν–ˆκ³  기닀릴 수 μžˆλŠ” μƒνƒœμΈ μžμ‹μ΄ μ—†μœΌλ©΄ waitid()κ°€ μ¦‰μ‹œ 0을 λ°˜ν™˜ν•˜λ©° infopκ°€ κ°€λ¦¬ν‚€λŠ” siginfo_t ꡬ쑰체의 μƒνƒœλŠ” κ΅¬ν˜„μ— 따라 λ‹€λ₯΄λ‹€. 이 경우λ₯Ό μžμ‹μ΄ 기닀릴 수 μžˆλŠ” μƒνƒœμ˜€λ˜ κ²½μš°μ™€ (이식성 μžˆλŠ” λ°©μ‹μœΌλ‘œ) κ΅¬λ³„ν•˜λ €λ©΄ 호좜 전에 si_pid ν•„λ“œλ₯Ό 0으둜 λ§Œλ“€κ³ μ„œ 호좜 λ°˜ν™˜ 후에 이 ν•„λ“œμ— 0 μ•„λ‹Œ 값이 μžˆλŠ”μ§€ ν™•μΈν•˜λ©΄ λœλ‹€.

POSIX.1-2008 기술 μ •μ˜€ν‘œ 1(2013λ…„)μ—μ„œλŠ” options에 WNOHANG을 μ§€μ •ν–ˆκ³  기닀릴 수 μžˆλŠ” μƒνƒœμΈ μžμ‹μ΄ μ—†μœΌλ©΄ waitid()κ°€ κ·Έ ꡬ쑰체의 si_pid 및 si_signo ν•„λ“œλ₯Ό 0으둜 μ±„μ›Œμ•Ό ν•œλ‹€λŠ” μš”κ΅¬ 사항을 μΆ”κ°€ν•œλ‹€. 이 μš”κ΅¬ 사항을 μ€€μˆ˜ν•˜λŠ” λ¦¬λˆ…μŠ€ 및 여타 κ΅¬ν˜„λ“€μ—μ„œλŠ” waitid() 호좜 전에 si_pid ν•„λ“œλ₯Ό 0으둜 λ§Œλ“€ ν•„μš”κ°€ μ—†λ‹€. ν•˜μ§€λ§Œ λͺ¨λ“  κ΅¬ν˜„λ“€μ΄ 이 μ μ—μ„œ POSIX.1 λͺ…μ„Έλ₯Ό λ”°λ₯΄μ§€λŠ” μ•ŠλŠ”λ‹€.

RETURN VALUE

wait(): 성곡 μ‹œ μ’…λ£Œν•œ μžμ‹μ˜ ν”„λ‘œμ„ΈμŠ€ IDλ₯Ό λ°˜ν™˜ν•œλ‹€. 였λ₯˜ μ‹œ -1을 λ°˜ν™˜ν•œλ‹€.

waitpid(): 성곡 μ‹œ μƒνƒœκ°€ 바뀐 μžμ‹μ˜ ν”„λ‘œμ„ΈμŠ€ IDλ₯Ό λ°˜ν™˜ν•œλ‹€. WNOHANG을 μ§€μ •ν–ˆκ³  pid둜 μ§€μ •ν•œ μžμ‹μ΄ ν•˜λ‚˜ 이상 μ‘΄μž¬ν•˜μ§€λ§Œ κ·Έ μžμ‹(λ“€)이 아직 μƒνƒœλ₯Ό λ°”κΎΈμ§€ μ•Šμ•˜μœΌλ©΄ 0을 λ°˜ν™˜ν•œλ‹€. 였λ₯˜ μ‹œ -1을 λ°˜ν™˜ν•œλ‹€.

waitid(): 성곡 μ‹œ, λ˜λŠ” WNOHANG을 μ§€μ •ν–ˆκ³  id둜 μ§€μ •ν•œ μ–΄λŠ μžμ‹λ„ 아직 μƒνƒœλ₯Ό λ°”κΎΈμ§€ μ•Šμ•˜μœΌλ©΄ 0을 λ°˜ν™˜ν•œλ‹€. 였λ₯˜ μ‹œ -1을 λ°˜ν™˜ν•œλ‹€.

이 ν˜ΈμΆœλ“€ 각각은 였λ₯˜ μ‹œμ— errnoλ₯Ό μ μ ˆν•œ κ°’μœΌλ‘œ μ„€μ •ν•œλ‹€.

ERRORS

ECHILD
(wait()μ—μ„œ) 호좜 ν”„λ‘œμ„ΈμŠ€μ—κ²Œ 아직 기닀리지 μ•Šμ€ μžμ‹μ΄ μ—†λ‹€.
ECHILD
(waitpid()λ‚˜ waitid()μ—μ„œ) pidλ‚˜(waitpid()) idtype 및 id둜(waitid()) μ§€μ •ν•œ ν”„λ‘œμ„ΈμŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šκ±°λ‚˜ 호좜 ν”„λ‘œμ„ΈμŠ€μ˜ μžμ‹μ΄ μ•„λ‹ˆλ‹€. (SIGCHLD에 λŒ€ν•œ λ™μž‘μ΄ SIG_IGN으둜 섀정돼 있으면 자기 μžμ‹μ— λŒ€ν•΄μ„œλ„ μ΄λ ‡κ²Œ 될 수 μžˆλ‹€. μŠ€λ ˆλ“œμ— λŒ€ν•œ λ¦¬λˆ…μŠ€ μ°Έκ³  사항 μ ˆλ„ μ°Έκ³ .)
EINTR
WNOHANG을 μ„€μ •ν•˜μ§€ μ•Šμ•˜μœΌλ©° 차단 μ•ˆ 된 μ‹œκ·Έλ„μ΄λ‚˜ SIGCHLDλ₯Ό μž‘μ•˜λ‹€. signal(7) μ°Έκ³ .
EINVAL
options μΈμžκ°€ μœ νš¨ν•˜μ§€ μ•Šλ‹€.

CONFORMING TO

SVr4, 4.3BSD, POSIX.1-2001.

NOTES

μ’…λ£Œλ˜μ—ˆλŠ”λ° κΈ°λ‹€λ € μ£Όμ§€ μ•Šμ€ μžμ‹μ€ "μ’€λΉ„"κ°€ λœλ‹€. μ»€λ„μ—μ„œλŠ” μ’€λΉ„ ν”„λ‘œμ„ΈμŠ€μ— λŒ€ν•œ μ΅œμ†Œν•œμ˜ 정보(PID, μ’…λ£Œ μƒνƒœ, μžμ› μ‚¬μš© 정보)λ₯Ό μœ μ§€ν•˜μ—¬ 이후 λΆ€λͺ¨κ°€ wait을 μˆ˜ν–‰ν•΄μ„œ μžμ‹μ— λŒ€ν•œ 정보λ₯Ό 얻을 수 μžˆλ„λ‘ ν•œλ‹€. wait을 톡해 μ‹œμŠ€ν…œμ—μ„œ μ œκ±°ν•˜μ§€ μ•ŠλŠ” ν•œ μ’€λΉ„λŠ” 컀널 ν”„λ‘œμ„ΈμŠ€ ν…Œμ΄λΈ”μ—μ„œ 자리λ₯Ό μ°¨μ§€ν•˜κ³  μžˆλŠ”λ‹€. 그리고 이 ν…Œμ΄λΈ”μ΄ 가득 μ°¨λ©΄ ν”„λ‘œμ„ΈμŠ€λ₯Ό μƒˆλ‘œ λ§Œλ“œλŠ” 게 λΆˆκ°€λŠ₯ν•΄μ§„λ‹€. λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œλ˜λ©΄ "μ’€λΉ„" μžμ‹λ“€μ΄ (μžˆλ‹€λ©΄) init(1)μ—κ²Œ (λ˜λŠ” prctl(2) PR_SET_CHILD_SUBREAPER λ™μž‘μ„ 톡해 μ§€μ •ν•œ κ°€μž₯ κ°€κΉŒμš΄ "μ„œλΈŒλ¦¬νΌ" ν”„λ‘œμ„ΈμŠ€μ—κ²Œ) μž…μ–‘λœλ‹€. 그러면 init(1)이 μžλ™μœΌλ‘œ wait을 μˆ˜ν–‰ν•˜μ—¬ μ’€λΉ„λ₯Ό μ œκ±°ν•œλ‹€.

POSIX.1-2001μ—μ„œλŠ” SIGCHLD 처리 방식을 SIG_IGN둜 μ„€μ •ν•˜κ±°λ‚˜ SIGCHLD에 SA_NOCLDWAIT ν”Œλž˜κ·Έλ₯Ό μ„€μ •ν•œ κ²½μš°μ— (sigaction(2) μ°Έκ³ ) μ’…λ£Œν•œ μžμ‹μ΄ μ’€λΉ„κ°€ λ˜μ§€ μ•ŠμœΌλ©° wait()μ΄λ‚˜ waitpid() 호좜이 λͺ¨λ“  μžμ‹μ΄ μ’…λ£Œν•  λ•ŒκΉŒμ§€ 블둝 λ˜μ—ˆλ‹€κ°€ errnoλ₯Ό ECHILD둜 ν•΄μ„œ μ‹€νŒ¨ν•˜κ²Œ λœλ‹€κ³  λͺ…μ„Έν•œλ‹€. (μ›λž˜ POSIX ν‘œμ€€μ—μ„œλŠ” SIGCHLDλ₯Ό SIG_IGN으둜 μ„€μ •ν–ˆμ„ λ•Œμ˜ λ™μž‘ 방식을 λͺ…μ„Έν•˜μ§€ μ•Šκ³  λ‚¨κ²¨λ‘μ—ˆλ‹€. 참고둜 SIGCHLD의 κΈ°λ³Έ 처리 방식이 "λ¬΄μ‹œ"μ΄μ§€λ§Œ 처리 방식을 λͺ…μ‹œμ μœΌλ‘œ SIG_IGN으둜 μ„€μ •ν•˜λ©΄ μ’€λΉ„ ν”„λ‘œμ„ΈμŠ€ μžμ‹ 처리 방식이 λ‹¬λΌμ§€λŠ” 것이닀.)

λ¦¬λˆ…μŠ€ 2.6은 POSIX μš”κ΅¬λ₯Ό μ€€μˆ˜ν•œλ‹€. ν•˜μ§€λ§Œ λ¦¬λˆ…μŠ€ 2.4(및 이전)μ—μ„œλŠ” κ·Έλ ‡μ§€ μ•Šμ•„μ„œ SIGCHLDκ°€ λ¬΄μ‹œλ˜λŠ” λ™μ•ˆ wait()μ΄λ‚˜ waitpid() ν˜ΈμΆœμ„ ν•˜λ©΄ SIGCHLDκ°€ λ¬΄μ‹œλ˜κ³  μžˆμ§€ μ•Šμ€ κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€. 즉, λ‹€μŒ μžμ‹ μ’…λ£Œ λ•ŒκΉŒμ§€ 호좜이 블둝 λ˜μ–΄ μžˆλ‹€κ°€ κ·Έ μžμ‹μ˜ ν”„λ‘œμ„ΈμŠ€ ID와 μƒνƒœλ₯Ό λ°˜ν™˜ν•œλ‹€.

λ¦¬λˆ…μŠ€ μ°Έκ³  사항

λ¦¬λˆ…μŠ€ μ»€λ„μ—μ„œ 컀널 μŠ€μΌ€μ€„ μŠ€λ ˆλ“œλŠ” ν”„λ‘œμ„ΈμŠ€μ™€ λšœλ ·ν•˜κ²Œ κ΅¬λ³„λ˜λŠ” μš”μ†Œκ°€ μ•„λ‹ˆλ‹€. μŠ€λ ˆλ“œλŠ” κ·Έμ € λ¦¬λˆ…μŠ€ 고유의 clone(2) μ‹œμŠ€ν…œ 호좜둜 λ§Œλ“€μ–΄μ§„ ν”„λ‘œμ„ΈμŠ€μΌ 뿐이닀. 그리고 이식성 μžˆλŠ” pthread_create(3) 같은 λ‹€λ₯Έ 루틴듀이 clone(2)으둜 κ΅¬ν˜„λ˜μ–΄ μžˆλ‹€. λ¦¬λˆ…μŠ€ 2.4 μ „μ—μ„œ μŠ€λ ˆλ“œλŠ” ν”„λ‘œμ„ΈμŠ€μ˜ νŠΉμˆ˜ν•œ 경우일 λΏμ΄μ—ˆκ³ , κ·Έλž˜μ„œ 같은 μŠ€λ ˆλ“œ 그룹에 속할 λ•Œμ—λ„ ν•œ μŠ€λ ˆλ“œκ°€ λ‹€λ₯Έ μŠ€λ ˆλ“œμ˜ μžμ‹μ„ 기닀릴 수 μ—†μ—ˆλ‹€. ν•˜μ§€λ§Œ POSIXμ—μ„œ κ·Έ κΈ°λŠ₯을 κ·œμ •ν•˜λ©΄μ„œ λ¦¬λˆ…μŠ€ 2.4λΆ€ν„°λŠ” μŠ€λ ˆλ“œκ°€ 같은 μŠ€λ ˆλ“œ κ·Έλ£Ή λ‚΄μ˜ λ‹€λ₯Έ μŠ€λ ˆλ“œμ˜ μžμ‹μ„ 기닀릴 수 있으며, 또 기본적으둜 κ·Έλ ‡κ²Œ ν•œλ‹€.

λ‹€μŒ λ¦¬λˆ…μŠ€ μ „μš© options 값듀은 clone(2)으둜 λ§Œλ“  μžμ‹λ“€μ— μ“°κΈ° μœ„ν•œ 것이닀. λ¦¬λˆ…μŠ€ 4.7λΆ€ν„° waitid()에도 μ“Έ 수 μžˆλ‹€.

__WCLONE
"클둠" μžμ‹λ§Œ κΈ°λ‹€λ¦°λ‹€. μ—†μœΌλ©΄ "비클둠" μžμ‹λ§Œ κΈ°λ‹€λ¦°λ‹€. ("클둠" μžμ‹μ€ μ’…λ£Œ μ‹œ 자기 λΆ€λͺ¨μ—κ²Œ μ‹œκ·Έλ„μ„ μ „λ‹¬ν•˜μ§€ μ•Šκ±°λ‚˜ SIGCHLD μ•„λ‹Œ μ‹œκ·Έλ„μ„ μ „λ‹¬ν•˜λŠ” μžμ‹μ΄λ‹€.) __WALL도 μ§€μ •ν•œ 경우 이 μ˜΅μ…˜μ€ λ¬΄μ‹œν•œλ‹€.
__WALL (λ¦¬λˆ…μŠ€ 2.4λΆ€ν„°)
μ’…λ₯˜("클둠", "비클둠")와 상관없이 λͺ¨λ“  μžμ‹μ„ κΈ°λ‹€λ¦°λ‹€.
__WNOTHREAD (λ¦¬λˆ…μŠ€ 2.4λΆ€ν„°)
같은 μŠ€λ ˆλ“œ 그룹의 λ‹€λ₯Έ μŠ€λ ˆλ“œμ˜ μžμ‹μ„ 기닀리지 μ•ŠλŠ”λ‹€. λ¦¬λˆ…μŠ€ 2.4 μ „μ—μ„œλŠ” 이게 κΈ°λ³Έμ΄μ—ˆλ‹€.

λ¦¬λˆ…μŠ€ 4.7λΆ€ν„°λŠ” μžμ‹μ„ ptrace ν•˜κ³  있으면 μžλ™μœΌλ‘œ __WALL ν”Œλž˜κ·Έλ₯Ό ν•¨μ˜ν•œλ‹€.

C 라이브러리/컀널 차이

wait()이 μ‹€μ œλ‘œλŠ” (glibcμ—μ„œ) wait4(2) 호좜둜 κ΅¬ν˜„λœ 라이브러리 ν•¨μˆ˜μ΄λ‹€.

μ–΄λ–€ μ•„ν‚€ν…μ²˜μ—λŠ” waitpid() μ‹œμŠ€ν…œ 호좜이 μ—†λ‹€. λŒ€μ‹  wait4(2)λ₯Ό ν˜ΈμΆœν•˜λŠ” C 라이브러리 래퍼 ν•¨μˆ˜λ₯Ό 톡해 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œλ‹€.

μ§„μ§œ waitid() μ‹œμŠ€ν…œ ν˜ΈμΆœμ€ struct rusage * νƒ€μž…μ˜ λ‹€μ„― 번째 인자λ₯Ό λ°›λŠ”λ‹€. 이 μΈμžκ°€ NULL이 μ•„λ‹ˆλ©΄ wait4(2)와 같은 μ‹μœΌλ‘œ 이λ₯Ό μ΄μš©ν•΄ μžμ‹μ— λŒ€ν•œ μžμ› μ‚¬μš© 정보λ₯Ό λ°˜ν™˜ν•œλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ getrusage(2)λ₯Ό 보라.

BUGS

POSIX.1-2008에 λ”°λ₯΄λ©΄ waitid()λ₯Ό ν˜ΈμΆœν•˜λŠ” μ‘μš©μ—μ„œ infopκ°€ siginfo_t ꡬ쑰체λ₯Ό 가리킀도둝 (즉 널 포인터가 μ•„λ‹ˆλ„λ‘) 보μž₯ν•΄μ•Ό ν•œλ‹€. λ¦¬λˆ…μŠ€μ—μ„œλŠ” infopκ°€ NULL이어도 waitid()κ°€ μ„±κ³΅ν•˜μ—¬ κΈ°λ‹€λ¦° μžμ‹μ˜ ν”„λ‘œμ„ΈμŠ€ IDλ₯Ό λ°˜ν™˜ν•œλ‹€. μ‘μš©μ—μ„œλŠ” 일관성 μ—†κ³  λΉ„ν‘œμ€€μ΄λ©° λΆˆν•„μš”ν•œ 이 λ™μž‘ 방식에 μ˜μ§€ν•˜λŠ” 것을 ν”Όν•΄μ•Ό ν•œλ‹€.

EXAMPLE

λ‹€μŒ ν”„λ‘œκ·Έλž¨μ€ fork(2)와 waitpid() μ‚¬μš© 방식을 보여 μ€€λ‹€. ν”„λ‘œκ·Έλž¨μ—μ„œ μžμ‹ ν”„λ‘œμ„ΈμŠ€λ₯Ό λ§Œλ“ λ‹€. ν”„λ‘œκ·Έλž¨μ— λͺ…λ Ήν–‰ 인자λ₯Ό μ£Όμ§€ μ•ŠμœΌλ©΄ μžμ‹μ΄ pause(2)λ₯Ό μ΄μš©ν•΄ 싀행을 λ©ˆμΆ”λŠ”λ°, κ·Έλ•Œ μ‚¬μš©μžκ°€ μžμ‹μ—κ²Œ μ‹œκ·Έλ„μ„ 보낼 수 μžˆλ‹€. λͺ…λ Ήν–‰ μΈμžκ°€ 있으면 λͺ…λ Ήν–‰μ—μ„œ μ€€ μ •μˆ˜λ₯Ό μ’…λ£Œ μƒνƒœλ‘œ μ‚¬μš©ν•΄μ„œ μžμ‹μ΄ μ¦‰μ‹œ μ’…λ£Œν•œλ‹€. λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€λŠ” 루프λ₯Ό λŒλ©΄μ„œ waitpid()둜 μžμ‹μ„ κ°μ‹œν•˜λ©°, μœ„μ—μ„œ μ„€λͺ…ν•œ W*() λ§€ν¬λ‘œλ“€μ„ μ΄μš©ν•΄ μ’…λ£Œ μƒνƒœ 값을 λΆ„μ„ν•œλ‹€.

λ‹€μŒ μ…Έ μ„Έμ…˜μ΄ ν”„λ‘œκ·Έλž¨ μ‚¬μš© 방식을 보여 μ€€λ‹€.

$ ./a.out &
Child PID is 32360
[1] 32359
$ kill -STOP 32360
stopped by signal 19
$ kill -CONT 32360
continued
$ kill -TERM 32360
killed by signal 15
[1]+  Done                    ./a.out
$

ν”„λ‘œκ·Έλž¨ μ†ŒμŠ€

#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
    pid_t cpid, w;
    int wstatus;

    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (cpid == 0) {            /* μžμ‹μ΄ μ‹€ν–‰ν•˜λŠ” μ½”λ“œ */
        printf("Child PID is %ld\n", (long) getpid());
        if (argc == 1)
            pause();                    /* μ‹œκ·Έλ„ 기닀리기 */
        _exit(atoi(argv[1]));

    } else {                    /* λΆ€λͺ¨κ°€ μ‹€ν–‰ν•˜λŠ” μ½”λ“œ */
        do {
            w = waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED);
            if (w == -1) {
                perror("waitpid");
                exit(EXIT_FAILURE);
            }

            if (WIFEXITED(wstatus)) {
                printf("exited, status=%d\n", WEXITSTATUS(wstatus));
            } else if (WIFSIGNALED(wstatus)) {
                printf("killed by signal %d\n", WTERMSIG(wstatus));
            } else if (WIFSTOPPED(wstatus)) {
                printf("stopped by signal %d\n", WSTOPSIG(wstatus));
            } else if (WIFCONTINUED(wstatus)) {
                printf("continued\n");
            }
        } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
        exit(EXIT_SUCCESS);
    }
}

SEE ALSO

_exit(2), clone(2), fork(2), ptrace(2), sigaction(2), signal(2), wait4(2), pthread_create(3), credentials(7), signal(7)


2018-04-30

⚠️ **GitHub.com Fallback** ⚠️