Do You Coding?
[function] waitpid ํจ์ ์์๋ณด๊ธฐ ๋ณธ๋ฌธ

๐ ๋งค๋ด์ผ (Linux)
NAME
waitpid - wait for process to change state
: ํ๋ก์ธ์ค๊ฐ ์ํ๋ฅผ ๋ณ๊ฒฝํ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ธฐ
SYNOPSIS
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *wstatus, int options);
DESCRIPTION
All of these system calls are used to wait for state changes in a child of the calling
process, and obtain information about the child whose state has changed. A state change is
considered to be: the child terminated; the child was stopped by a signal; or the child was
resumed by a signal. In the case of a terminated child, performing a wait allows the system
to release the resources associated with the child; if a wait is not performed, then the terโ
minated child remains in a "zombie" state (see NOTES below).
If a child has already changed state, then these calls return immediately. Otherwise, they
block until either a child changes state or a signal handler interrupts the call (assuming
that system calls are not automatically restarted using the SA_RESTART flag of sigaction(2)).
In the remainder of this page, a child whose state has changed and which has not yet been
waited upon by one of these system calls is termed waitable.
wait() and waitpid()
The wait() system call suspends execution of the calling thread until one of its children terโ
minates. The call wait(&wstatus) is equivalent to:
waitpid(-1, &wstatus, 0);
The waitpid() system call suspends execution of the calling thread until a child specified by
pid argument has changed state. By default, waitpid() waits only for terminated children, but
this behavior is modifiable via the options argument, as described below.
The value of pid can be:
< -1 meaning wait for any child process whose process group ID is equal to the absolute
value of pid.
-1 meaning wait for any child process.
0 meaning wait for any child process whose process group ID is equal to that of the callโ
ing process at the time of the call to waitpid().
> 0 meaning wait for the child whose process ID is equal to the value of pid.
: ์ด ๋ชจ๋ ์์คํ
ํธ์ถ์ ํธ์ถ ๊ณผ์ ์ ์์์์ ์ํ ๋ณ๊ฒฝ์ ๋๊ธฐํ๊ณ ์ํ๊ฐ ๋ณ๊ฒฝ๋ child์ ๋ํ
์ ๋ณด๋ฅผ ์ป๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ํ ๋ณ๊ฒฝ์ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ฃผ๋ฉ๋๋ค. child๊ฐ ์ข
๋ฃ๋๊ฑฐ๋,
์ ํธ์ ์ํด child๊ฐ ์ค์ง๋๊ฑฐ๋, ์ ํธ์ ์ํด ๋ค์ ์์๋ฉ๋๋ค. ์ข
๋ฃ๋ child์ ๊ฒฝ์ฐ,
๋๊ธฐ๋ฅผ ์ํํ๋ฉด ์์คํ
์ด child๊ณผ ๊ด๋ จ๋ ๋ฆฌ์์ค๋ฅผ ํด์ ํ ์ ์๊ณ , ๋๊ธฐ๋ฅผ ์ํํ์ง ์์ผ๋ฉด
์ข
๋ฃ๋ child๋ "์ข๋น" ์ํ๋ก ์ ์ง๋ฉ๋๋ค(์๋ ์ฐธ๊ณ ์ฐธ์กฐ).
child๊ฐ ์ด๋ฏธ ์ํ๋ฅผ ๋ณ๊ฒฝํ ๊ฒฝ์ฐ ์ด๋ฌํ ํธ์ถ์ ์ฆ์ ๋ฐํ๋ฉ๋๋ค.
๊ทธ๋ ์ง ์์ผ๋ฉด child์ด ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ฑฐ๋ ์ ํธ ์ฒ๋ฆฌ๊ธฐ๊ฐ ํธ์ถ์ ์ค๋จํ ๋๊น์ง
(์๊ทธ์ก์
(2)์ SA_RESTART ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ ์์คํ
ํธ์ถ์ด ์๋์ผ๋ก
๋ค์ ์์๋์ง ์๋๋ค๊ณ ๊ฐ์ ํ ๋) ์ฐจ๋จ๋ฉ๋๋ค.
์ด ํ์ด์ง์ ๋๋จธ์ง ๋ถ๋ถ์์๋ ์ํ๊ฐ ๋ณ๊ฒฝ๋์ด ์์ง ์ด๋ฌํ ์์คํ
ํธ์ถ ์ค ํ๋๊ฐ
๋๊ธฐํ์ง ์์ child๋ฅผ ๋๊ธฐ ๊ฐ๋ฅ ์ํ๋ผ๊ณ ํฉ๋๋ค.
wait() and waitpid()
wait() ์์คํ
ํธ์ถ์ ํ์ ํธ์ถ ์ค ํ๋๊ฐ ์ข
๋ฃ๋ ๋๊น์ง ํธ์ถ ์ค๋ ๋์ ์คํ์ ์ค์งํฉ๋๋ค.
ํธ์ถ wait(&wstatus)๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
waitpid (- 1, &wstatus, 0);
waitpid() ์์คํ
ํธ์ถ์ pid ์ธ์์ ์ํด ์ง์ ๋ child์ด ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๊น์ง ํธ์ถ ์ค๋ ๋์ ์คํ์ ์ค์งํฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก waitpid()๋ ์ข
๋ฃ๋ child๋ง ๋๊ธฐํ์ง๋ง, ์ด ๋์์ ์๋ ์ค๋ช
๋ ๋๋ก ์ต์
์ธ์๋ฅผ ํตํด ์์ ํ ์ ์์ต๋๋ค.
pid ๊ฐ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
< -1์ ํ๋ก์ธ์ค ๊ทธ๋ฃน ID๊ฐ pid์ ์ ๋๊ฐ๊ณผ ๋์ผํ ํ์ ํ๋ก์ธ์ค๋ฅผ ๋๊ธฐํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
-1์ ๋ชจ๋ ์์ ํ๋ก์ธ์ค๋ฅผ ๊ธฐ๋ค๋ฆด ๊ฒ์ ์๋ฏธํฉ๋๋ค.
0์ ํธ์ถ ์ ํ๋ก์ธ์ค ๊ทธ๋ฃน ID๊ฐ ํธ์ถ ํ๋ก์ธ์ค ID์ ๋์ผํ ํ์ ํ๋ก์ธ์ค๋ฅผ waitpid()๋ก ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
> 0์ ํ๋ก์ธ์ค ID๊ฐ pid ๊ฐ๊ณผ ๋์ผํ child๋ฅผ ๊ธฐ๋ค๋ฆฐ๋ค๋ ๋ป์
๋๋ค.
RETURN VALUE
waitpid(): on success, returns the process ID of the child whose state has changed; if WNOHANG
was specified and one or more child(ren) specified by pid exist, but have not yet changed
state, then 0 is returned. On error, -1 is returned.
Each of these calls sets errno to an appropriate value in the case of an error.
: ์ฑ๊ณต ์ ์ํ๊ฐ ๋ณ๊ฒฝ๋ ์์์ ํ๋ก์ธ์ค ID๋ฅผ ๋ฐํํฉ๋๋ค.
WNOHANG์ด ์ง์ ๋์๊ณ pid๋ก ์ง์ ๋ ์์(์๋ )์ด ํ๋ ์ด์ ์กด์ฌํ์ง๋ง ์ํ๊ฐ ์์ง ๋ณ๊ฒฝ๋์ง ์์ ๊ฒฝ์ฐ
0์ด ๋ฐํ๋ฉ๋๋ค. ์ค๋ฅ ์ -1์ด ๋ฐํ๋ฉ๋๋ค. ์ด๋ฌํ ๊ฐ ํธ์ถ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ ์ ํ ๊ฐ์ผ๋ก errno๋ฅผ ์ค์ ํฉ๋๋ค.
๐ ํจ์ ์ค๋ช
waitpid ํจ์๋ wait ํจ์์ ๋ฌ๋ฆฌ ์ํ๋ pid์ child process๋ฅผ ๊ธฐ๋ค๋ฆด ์ ์๋ ํจ์์ด๋ค.
pid_t waitpid(pid_t pid, int *status, int options); ์ ํํ์ด๊ณ , ์ธ์๋ก ๋ฐ๋ pid์ ๋ฐ๋ผ waitpid์ ์ฒ๋ฆฌ๊ฐ ๋ฌ๋ผ์ง๋ค.
pid์ ๋ฐ๋ผ์ ์ด๋ ํ ํ๋ก์ธ์ค๋ฅผ ๊ธฐ๋ค๋ฆด์ง๋ฅผ ์ง์ ํ ์ ์๋๋ฐ, ๋ค์๊ณผ ๊ฐ์ ์ต์ ์ผ๋ก ์ด๋ค์ ธ์๋ค.
< ์ธ์ pid์ ๋ฐ๋ฅธ ์ต์ >
| pid == -1 | ์์์ ์์ ํ๋ก์ธ์ค |
| pid > 0 | ํ๋ก์ธ์ค ID๊ฐ pid์ ๊ฐ๊ณผ ๊ฐ์ ์์ ํ๋ก์ธ์ค |
| pid == 0 | ํ๋ก์ธ์ค ๊ทธ๋ฃน ID๊ฐ ํธ์ถํ ํ๋ก์ธ์ค์ ID์ ๊ฐ์ ํ๋ก์ธ์ค |
| pid < -1 | ํ๋ก์ธ์ค ๊ทธ๋ฃน ID๊ฐ pid์ ์ ๋๊ฐ๊ณผ ๊ฐ์ ์์์ ์์ ํ๋ก์ธ์ค |
์ฐ์ ํ๋ก์ธ์ค ๊ทธ๋ฃน์ด๋, ๊ด๋ จ์๋ ํ๋ก์ธ์ค๋ฅผ ๋ฌถ์ ๊ฒ์ผ๋ก Process Group ID๋ฅผ ๋ถ์ฌ๋ฐ๋๋ค.
ํ๋ก์ธ์ค๋ ๊ทธ๋ฃน ๋ฉค๋ฒ๊ฐ ๋๋ฉฐ, ์์์ ํ์ดํ๋ก ์ฐ๊ฒฐํ๋ฉด์ ํ๋ก์ธ์ค ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด ํ ์์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
๋ํ, ํ๋ก์ธ์ค ๊ทธ๋ฃน ๋ฆฌ๋๊ฐ ์กด์ฌํ๋ฉฐ, ๊ทธ๋ฃน ๋ฆฌ๋์ PID๊ฐ PGID(Process Group ID)๊ฐ ๋๋ค. (๋ฆฌ๋ ๋ณ๊ฒฝ ๊ฐ๋ฅ)
์ ํ์ ์ ํ ํด๋น ํ๋ก์ธ์ค๊ฐ waitํ ๋์์ด ๋๊ณ , ๊ฐ๊ฐ ์ค๋ช ํ๋ฉด,
-1์ผ ๋๋, wait() ํจ์์ ๋์ผํ๊ฒ ํ๋์ ์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃํ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค. (waitpid(-1, &status, 0))
0 ๋ณด๋ค ํด ๋๋, ํด๋น pid์ ์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃํ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.
0์ผ ๋๋, ํ์ฌ ํ๋ก์ธ์ค์ ๊ทธ๋ฃน ID์ ๊ฐ์ ๊ทธ๋ฃน์ ์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃํ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.
-1๋ณด๋ค ์์ ๋๋, ๊ทธ๋ฃน ID๊ฐ pid๋ก ๋ฐ์ ๊ฐ์ ์ ๋๊ฐ๊ณผ ๊ฐ๊ณ , ํด๋น ๊ทธ๋ฃน์ ์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃํ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.
๊ทธ๋ฆฌ๊ณ , 3๋ฒ์งธ ์ธ์์ธ options์๋ 0, WNOHANG, WCONTINUED, WUNTRACED ๋ฑ์ด ๋ค์ด๊ฐ๋ฉฐ,
์ผ๋ฐ์ ์ผ๋ก WNOHANG(์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋์๋์ง ์คํ์ค์ธ์ง๋ง ํ์ธํ๊ณ ๊ธฐ๋ค๋ฆฌ์ง๋ ์์.) ๊ณผ
0 (์ผ๋ฐ wait ํจ์์ฒ๋ผ ์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆผ.) ์ ๋ง์ด ์ฌ์ฉํ๋ค.
๋ฐํ๊ฐ์ wait์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ข ๋ฃ๋ ์์ ํ๋ก์ธ์ค์ ํ๋ก์ธ์ค ID๋ฅผ return ํ๊ณ , ์คํจํ๋ฉด -1์ ๋ฐํํ๋ค.
์ถ๊ฐ์ ์ผ๋ก 'WNOHANG์ options์ผ๋ก ์ฌ์ฉํ๋ฉด์ ์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋์ง ์์๋ค๋ฉด' 0์ ๋ฐํํ๋ค.
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
int pid = fork();
int status;
if (pid == 0)
{
sleep(5);
printf("Child Process Ended\n");
exit(0);
}
while(waitpid(pid, &status, WNOHANG) == 0)
{
sleep(1);
printf("waiting...\n");
}
printf("Parent Process Ended\n");
exit(0);
}
์ถ๋ ฅ - std_output)

waitpid์ options์ WNOHANG์ผ๋ก ์ฌ์ฉํ๊ณ while๋ฌธ์ 0์ผ ๋์ ์กฐ๊ฑด์ ์ฃผ์๋๋ฐ,
'WNOHANG์ options์ผ๋ก ์ฌ์ฉํ๋ฉด์ ์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋์ง ์์๋ค๋ฉด' 0์ ๋ฐํํ๋ ์ํฉ์ ์ด์ฉํ ์ฝ๋์ด๋ค.
์์์ sleep์ 5์ด๊ฐํ๊ณ ์ดํ์ Child Process Ended ๋ผ๋ ๋ฌธ๊ตฌ๋ฅผ ์ถ๋ ฅํ๋ค.
waitpid๋ ๋ถ๋ชจ ํ๋ก์ธ์ค๊ฐ ๊ทธ ์์์ด ์ข ๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด ์๋, ๋ฐ๋ก 0์ ๋ฐํํ๊ฒ ๋๋ฏ๋ก,
while๋ฌธ ์์ ๋ด์ฉ์ ์คํํ์ฌ 1์ด sleep ํ, waiting... ์ ์ถ๋ ฅํ๋ค.
๊ทธ๋ฆฌ๊ณ ์์์ด ์ข ๋ฃ๋๋ฉด, ์ด์ ๋ถ๋ชจ ํ๋ก์ธ์ค๋ waitpid๊ฐ 0์ด ์๋ ์์์ pid๋ฅผ ๋ฐํํ๋ฏ๋ก ๋ฐ๋ณต๋ฌธ์ด ์ข ๋ฃ๋๊ณ ,
Parent Process Ended๊ฐ ์ถ๋ ฅ๋๋ฉฐ ๋ชจ๋ ์ข ๋ฃ๋๋ค.
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
int pid = fork();
int status;
if (pid == 0)
{
sleep(5);
printf("Child Process Ended\n");
exit(0);
}
while(waitpid(pid, &status, 0) == 0)
{
sleep(1);
printf("waiting...\n");
}
printf("Parent Process Ended\n");
exit(0);
}
์ถ๋ ฅ - std_output)

์ฒซ๋ฒ์งธ ์ฝ๋์์ waitpid์ options์ 0์ผ๋ก ๋ฐ๊พผ ๋ค์ ๊ฒฐ๊ณผ์ด๋ค.
๊ทธ๋ผ wait() ํจ์์ ๋์ผํ๊ฒ ์๋ํ๋ฉฐ, ์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ค, ์ข ๋ฃ๋๋ฉด
ํด๋น ์์ ํ๋ก์ธ์ค์ pid๋ฅผ ๋ฐํํ๋ฏ๋ก ๋ฐ๋ณต๋ฌธ์ด ์คํ๋์ง ์๋๋ค.
๊ทธ๋ฆฌํ์ฌ, Child, Parent์ ํ๋ก์ธ์ค ์ข ๋ฃ ์ถ๋ ฅ๋ง ๋๊ณ ๋์ด ๋๋ค.
'CS & Engineering > C' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [library] strjoin ๊ตฌํํ๊ธฐ (0) | 2024.06.26 |
|---|---|
| [library] substr ๊ตฌํํ๊ธฐ (0) | 2024.06.18 |
| [function] wait ํจ์ ์์๋ณด๊ธฐ (0) | 2024.06.09 |
| [function] unlink ํจ์ ์์๋ณด๊ธฐ (2) | 2024.06.07 |
| [function] pipe ํจ์ ์์๋ณด๊ธฐ (0) | 2024.06.06 |