From: Ian Leitch Date: 2009-07-14T07:44:46+09:00 Subject: Re: rb_eval_string blocks on loops even if run inside a thread. --0016362834ee7af11a046e9e1112 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Thanks, I did think of using pthreads, though the code I need to eval will regularly touch any number of existing objects so I don't think there's a way to stay safe using pthreads. Do you know how to spawn a ruby green thread in C? 2009/7/13 > On 7/13/09, Ian Leitch wrote: > > I'm trying to use rb_eval_string to execute a bunch of code and return > from > > it straight away. My problem is that the code I want to eval contains a > > continuous loop. Even if I wrap the code in a thread the call still > blocks > > due to the loop. Note that I don't get the same behaviour when using > eval() > > outside of the C API. > > > > E.g: > > > > rb_eval_string("Thread.new { loop { puts 1; sleep 0.2 }}"); <-- blocks > > eval("Thread.new { loop { puts 1; sleep 0.2 }}") <--- doesn't block > > > > My guess is to spawn a ruby thread in C and call rb_eval_string inside > that, > > I can't find any examples of using the thread functions on google though > so > > I'm a bit stuck. Could someone give me a few pointers or perhaps some > > example code? > > This is the first time I have ever tried embedding Ruby in C, but I > hope it helps. (The idea is to run ruby from a C thread so the rest > of your C program can maybe run in parallel): > > > #include > > #include > #include > #include > > void *do_ruby(void* param) > { > ruby_init(); > rb_eval_string("loop { puts 'hello from ruby world'; sleep 5 }"); > ruby_finalize(); > } > > int main(int argc, char *argv[]) > { > pthread_t ruby_thread; > > printf("BEFORE DO_RUBY\n"); > > pthread_create( &ruby_thread, NULL, do_ruby, NULL); > > printf("AFTER DO_RUBY\n"); > > pthread_join(ruby_thread, NULL); > > return 0; > } > > > > gcc -o foo -lpthread -lruby1.8 -I/usr/lib/ruby/1.8/i486-linux foo.c > > ./foo > BEFORE DO_RUBY > hello from ruby world > AFTER DO_RUBY > hello from ruby world > hello from ruby world > ^C(eval): (eval):0:in `sleep': (Interrupt) > from (eval):0 > from (eval):0:in `loop' > from (eval):0 > (eval): [BUG] Segmentation fault > ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux] > > Abort > > > But, be aware: > "ruby is not thread-safe. If you embed ruby into a multi-threaded > application then you will need to semaphore protect all access to > ruby. Warning: Insufficient semaphore protection can be hard > debuggable." [1] > > [1] http://metaeditor.sourceforge.net/embed/#id2842564 > > --0016362834ee7af11a046e9e1112--