Skip to content

Instantly share code, notes, and snippets.

@kjunichi
Last active August 29, 2015 14:18
Show Gist options
  • Save kjunichi/235f7c5afac9125a150f to your computer and use it in GitHub Desktop.
Save kjunichi/235f7c5afac9125a150f to your computer and use it in GitHub Desktop.
mrubyのProcess.forkがC言語からだとうまく動かない問題
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "mruby.h"
#include "mruby/proc.h"
#include <mruby/compile.h>
#include <mruby/string.h>
mrb_value mrb_get_backtrace(mrb_state *mrb, mrb_value self);
int gCnt=0;
static mrb_value myfunc(mrb_state *mrb, mrb_value obj) {
printf("myfunc: start\n");
gCnt++;
printf("myfunc: end\n");
fflush(stdout);
return mrb_nil_value();
}
int main() {
FILE *f;
struct RProc *blk;
mrb_state *mrb;
mrb_value val,proc;
mrb = mrb_open();
f = fopen("fork.rb", "r");
mrb_load_file(mrb, f);
fclose(f);
fflush(stdout);
blk = mrb_proc_new_cfunc(mrb, myfunc);
proc = mrb_obj_value(blk);
val = mrb_funcall_with_block(mrb, mrb_top_self(mrb), mrb_intern_cstr(mrb, "mymethod"), 0, NULL, proc);
mrb_funcall(mrb,mrb_top_self(mrb),"p",1,proc);
fflush(stdout);
printf("gCnt = [%d]\n",gCnt);
printf("next is forking..\n");
val = mrb_funcall_with_block(mrb, mrb_obj_value(mrb_module_get(mrb, "Process")), mrb_intern_cstr(mrb, "fork"), 0, NULL, proc);
if(mrb->exc) {
mrb_value exc = mrb_obj_value(mrb->exc);
// エラー内容を取得
mrb_value backtrace = mrb_get_backtrace(mrb, exc);
printf("%s",mrb_str_to_cstr(mrb, mrb_inspect(mrb, backtrace)));
//
}
perror("check fork");
fflush(stdout);
mrb_funcall(mrb,mrb_top_self(mrb),"p",1,val);
mrb_funcall(mrb,mrb_obj_value(mrb_module_get(mrb, "Process")),"waitpid",1,val);
if(mrb->exc) {
mrb_value exc = mrb_obj_value(mrb->exc);
// [34m~B�[34m~C�[34m~C�[34m~F~E容[34m~B~R[34m~O~V[34m~W
mrb_value backtrace = mrb_get_backtrace(mrb, exc);
printf("%s",mrb_str_to_cstr(mrb, mrb_inspect(mrb, backtrace)));
}
printf("gCnt = [%d]\n",gCnt);
return 0;
}
def mymethod(&blk)
p "Hello, this is mymethod."
yield
pid = Process.fork(&blk)
Process.waitpid pid
end
mymethod {p "test"}
./a.out
"Hello, this is mymethod."
"test"
f_fork: I'm child
b is not nil
"test"
now child process is exitting!
"Hello, this is mymethod."
myfunc: start
myfunc: end
f_fork: I'm child
b is not nil
#<Proc:0x7f891c025ae0>
gCnt = [1]
next is forking..
check fork: Undefined error: 0
56386
f_fork: I'm child
b is not nil
gCnt = [1]
static mrb_value
mrb_f_fork(mrb_state *mrb, mrb_value klass)
{
mrb_value b, result;
int pid;
mrb_get_args(mrb, "&", &b);
switch (pid = fork()) {
case 0:
printf("f_fork: I'm child\n");
if (!mrb_nil_p(b)) {
printf("b is not nil\n");
mrb_yield(mrb, b, result);
printf("now child process is exitting!\n");
fflush(stdout);
_exit(0);
}
printf("oops b is nil!\n");
return mrb_nil_value();
case -1:
mrb_sys_fail(mrb, "fork failed");
return mrb_nil_value();
default:
return mrb_fixnum_value(pid);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment