caml_release_runtime_system导致的死锁问题
            
            
        
        
            Jun 28, 2023
         
     
    
 
    
    给出一个test.ml:
1 Printf .eprintf "hello from OCaml\n%!" 
 
和test-ocaml-5.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include  <stdio.h>  #include  <stdlib.h>  #include  <caml/misc.h>  #include  <caml/callback.h>  #include  <caml/threads.h>  int main  (int  argc, char  *argv[])   {     fprintf  (stderr , "starting up ...\n" );     caml_startup (argv);     fprintf  (stderr , "acquiring ...\n" );     caml_acquire_runtime_system ();     fprintf  (stderr , "acquired\n" );               caml_release_runtime_system ();     exit  (0 );   } 
 
然后用OCaml5的ocaml native compiler编译一下(这里我用的是ocaml-variants.5.0.0+options): 
ocamlopt -g test-ocaml-5.c test.ml -o test-ocaml-5
运行test-ocaml-5 会出现:
1 2 3 4 5 6 starting up ... hello from OCaml acquiring ... Fatal error: Fatal error during lock: Resource deadlock avoided [1]    8998 IOT instruction (core dumped)  ./test-ocaml-5 
 
这里我尝试了一下 4.14.0 和 4.14.1 , 都没有出现这个情况,而如果用threads编译的话: 
ocamlopt -g -I +unix unix.cmxa -I +threads threads.cmxa test-ocaml-5.c test.ml -o test-ocaml-5
无论在5.0还是4.14.x,都会挂起。
出现这个问题的一个可能原因是,在test-ocaml-5.c中,我在开头调用了caml_startup(),这会让当前线程获取锁,而caml_acquire_runtime_system()会再次获取它,caml_acquire_runtime_system() 应该在caml_release_runtime_system()之后调用:
1 2 3 4 5 6 7 8 9 10 11 int main (int  argc, char  *argv[] )   {     fprintf (stderr, "starting up ...\n" );     caml_startup (argv);     fprintf (stderr, "acquiring ...\n" );     caml_release_runtime_system () ;     caml_acquire_runtime_system () ;     fprintf (stderr, "acquired\n" );     exit (0 );   } 
 
运行结果为:
1 2 3 4 starting up ... hello from OCaml acquiring ... acquired