BlankTar

about | blog | works | photo

linuxだとforkってやつをよく聞くけれど、実際どんなもんなんだろうと思って息抜きがてら試してみた。

unistd.hで定義されているforkって関数を呼ぶだけでプロセスを二つに分けられるらしい。子プロセスには0が、親プロセスには子プロセスのpidが返るらしい。エラーだと-1らしい。
sys/wait.hwaitって関数で子プロセスが止まるのを待てるらしい。waitpidを使えば特定の子プロセスを待てるらしい。
waitの引数はNULLかintへのポインタで、子プロセスの戻り値を受け取れるらしい。

プロセス間で通信するにはパイプを使うのが手っ取り早そうだ。
同じくunistd.hpipe関数でパイプを作れる。戻り値は0なら成功、-1なら失敗。引数で渡したintが2つ分の配列に作ったパイプのファイルディスクリプタが入る。0番目が読み込み、1番目が書き込み、のようだ。
作ったパイプはread/writeで読み書きできる。ファイルディスクリプタなんでselectとかも使えると思う。試してないけど。

まあ細かいことは面倒くさいのでソースコード。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

// 子プロセス
//  helloって送って、worldを受け取る。パイプを閉じて死ぬ。
//  パイプを作っているのが親(というかフォーク前)なのだから、後片付けはwait後にやった方が自然な気がするけれど、まあ良いか。
void child(static int r, static int w)
{
	char buf[1024];

	write(w, "hello", 6);
	printf("child> send> hello\n");

	while(read(r, buf, sizeof(buf)) <= 0);
	printf("child> recv> s\n");

	close(r);
	close(w);
}

// 親プロセス
//  helloを受け取って、worldを送る。そしたらパイプを閉じて死ぬ。
void parent(static int r, static int w)
{
	char buf[1024];

	while(read(r, buf, sizeof(buf)) <= 0);
	printf("parent> recv>  s\n", buf);

	write(w, "world", 6);
	printf("parent> send> world\n");

	close(r);
	close(w);
}

void main()
{
	int p2c[2], c2p[2];

	// パイプを作る。双方向通信したいので2セット作る。
	pipe(p2c);
	pipe(c2p);

	if(fork() == 0)  // ここでフォーク。子プロセスが一つなのでpidは無視して、親か子かだけ判定。
	{
		child(p2c[0], c2p[1]);
	}else
	{
		parent(c2p[0], p2c[1]);
		wait(NULL);
	}

	return 0;
}
それなりの長さのソースコードに見えて、プロセス管理はforkとwaitの行の二つしかない。パイプもpipeで作ってcloseで閉じてるだけだ。めっちゃ簡単。
windowsのプロセス生成は何だか面倒くさかった覚えがあるので、この手軽さはかなり魅力的かも。
イメージ的にはまるっとコピーするforkは処理が重たそうだけれど、wikipedia曰くコピーオンライトらしいからそんなに重くないのかもしれない。

ちなみに、親が子を待たずに死んでもtopコマンドでは0 zombieのままだった。
調べてみたら、こういうプロセスのことを孤児プロセスと言うらしい。凄いそのまんまなネーミングだ。
自分を生んだ親が死んだらinitプロセスを里親にするらしい。その名もリペアレンティング。日本語で最育成だとさ。
initプロセスが親になるので、死ぬときはinitに看取ってもらえる。なのでゾンビにはならないそうな。

まあそんなわけで。何だかとっても適当な感じの記事になってしまった。

参考:
謎のC言語ブログ: プロセス間通信 (fork,pipe) によるメッセージの送受信
Man page of FORK
Man page of WAIT
Man page of PIPE
子プロセス - Wikipedia
< ASUS EeeBook x205TAにArch Linuxを入れてみた python/OpenCVでwebカメラを使ったlinuxの液晶の明るさ自動調整 >