LoginSignup
1
1

More than 3 years have passed since last update.

fork()関数、execve()関数について

Last updated at Posted at 2020-02-19
  • 自分用メモ
  • カーネルのプロセス生成について学んだことを残しておく
  • 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()関数について

  • 以下の流れでカーネルはプロセスを実行する
  1. 実行ファイルを読み込む
  2. 現在のプロセスのメモリを新たなプロセスのデータで上書き
  3. 新しいプロセスを実行
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が実行されていることが分かる

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1