- 自分用メモ
- カーネルのプロセス生成について学んだことを残しておく
- C言語で実行
fork()関数について
- fork()関数を実行すると、親プロセスから子プロセスを生み出す
fork.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
static void child()
{
printf("Child. pid: %d.\n", getpid());
exit(EXIT_SUCCESS);
}
static void parent(pid_t pid_child)
{
printf("Parent. parent's pid: %d. child's pid: %d\n", getpid(), pid_child);
exit(EXIT_SUCCESS);
}
int main()
{
pid_t pid;
pid = fork();
if(pid == -1) err(EXIT_FAILURE, "fork() failed");
//子プロセスは返り値が0
if(pid == 0)
child();
//親プロセスが返り値が子プロセスのプロセスID(> 0)
else
parent(pid);
}
- 実行結果
Parent. parent's pid: 27701. child's pid: 27702
Child. pid: 27702.
親プロセスから子プロセスが生成され、それぞれ別のプロセスIDを持っていることが分かる
execv()関数について
- 以下の流れでカーネルはプロセスを実行する
- 実行ファイルを読み込む
- 現在のプロセスのメモリを新たなプロセスのデータで上書き
- 新しいプロセスを実行
execve.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
static void child()
{
char *args[] = {"/bin/echo", "こんにちは", NULL};
printf("child. child's pid: %d.\n", getpid());
execve("/bin/echo", args, NULL);
err(EXIT_FAILURE, "execve() failed");
}
static void parent(pid_t pid_child)
{
printf("parent. parent's pid: %d. child's pid: %d\n", getpid(), pid_child);
exit(EXIT_SUCCESS);
}
int main(void)
{
pid_t pid;
pid = fork();
if(pid == -1)
err(EXIT_FAILURE, "fork() failed");
if(pid == 0)
child();
else
parent(pid);
}
- 実行結果
parent. parent's pid: 28034. child's pid: 28035
child. child's pid: 28035.
こんにちは
fork()関数でプロセスが分岐したあと、子プロセスでexecve()関数によって、/bin/echoが実行されていることが分かる