なかだです。

At Sun, 26 Nov 2000 15:41:14 +0900,
Tanaka Akira <akr / m17n.org> wrote:
> (書くのを忘れていたので追記しておきますが、殺すのは子プロセス側での話
> で、親プロセス側では当然、動いたままです。)

  これは当然ですね。

> で、疑問なのはプロセス外との通信を(直接には)行なわない thread について
> です。thread プログラミングは素人(じつは今回初めて thread を使った)な
> のでよくわからないのですが、そういうものは fork 時にどのような振舞を示
> すのが適切なことが多いんでしょうか? それともそんな thread は普通使われ
> ない?

  thread というのは単一のプロセスを共有するのが特徴なわけで、プ
ロセスを跨いだ thread というもの自体がそもそもあるはずがないと
思いますが。

  で、こんな感じで考えてみました。


diff -up current/eval.c devel/eval.c --- current/eval.c Thu Nov 23 23:19:11 2000 +++ devel/eval.c Sun Nov 26 13:03:53 2000 @@ -6732,6 +6732,7 @@ thread_free(th) if (th->stk_ptr) free(th->stk_ptr); th->stk_ptr = 0; if (th->locals) st_free_table(th->locals); + th->locals = 0; if (th->status != THREAD_KILLED) { if (th->prev) th->prev->next = th->next; if (th->next) th->next->prev = th->prev; @@ -8329,6 +8330,34 @@ thgroup_add(group, thread) th->gid = data->gid; return group; +} + +int +rb_sys_fork() +{ + int pid = fork(); + + if (pid == 0) { + rb_thread_t th; + + main_thread = curr_thread; + FOREACH_THREAD(th) { + if (th != curr_thread) { + rb_thread_ready(th); + th->status = THREAD_KILLED; + if (th->stk_ptr) free(th->stk_ptr); + th->stk_ptr = 0; + if (th->locals) st_free_table(th->locals); + th->locals = 0; + th->gid = 0; + th->priority = 0; + } + } + END_FOREACH(th); + curr_thread->prev = curr_thread->next = curr_thread; + } + + return pid; } void diff -up current/intern.h devel/intern.h --- current/intern.h Thu Nov 23 23:19:11 2000 +++ devel/intern.h Sun Nov 26 09:31:07 2000 @@ -167,6 +167,7 @@ VALUE rb_thread_current _((void)); VALUE rb_thread_main _((void)); VALUE rb_thread_local_aref _((VALUE, ID)); VALUE rb_thread_local_aset _((VALUE, ID, VALUE)); +int rb_sys_fork _((void)); /* file.c */ int eaccess _((const char*, int)); VALUE rb_file_s_expand_path _((int, VALUE *)); diff -up current/process.c devel/process.c --- current/process.c Mon Nov 13 23:19:12 2000 +++ devel/process.c Sun Nov 26 15:14:35 2000 @@ -534,14 +534,15 @@ rb_f_fork(obj) int pid; rb_secure(2); - switch (pid = fork()) { + switch (pid = rb_sys_fork()) { case 0: #ifdef linux after_exec(); #endif if (rb_block_given_p()) { - rb_yield(Qnil); - _exit(0); + int status; + rb_protect(rb_yield, Qnil, &status); + _exit(status ? -1 : 0); } return Qnil;
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦