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