blob: f183d391cd01d03f5c250212845ff1a7703e052c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
---
title: caml_release_runtime_system导致的死锁问题
date: 2023-06-28 21:45:55
tags: [Technique]
---
给出一个`test.ml`:
```ocaml
Printf.eprintf "hello from OCaml\n%!"
```
和`test-ocaml-5.c`:
```c
#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");
// here is where I would be calling an OCaml callback
// omitted for simplicity
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` 会出现:
```
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()`之后调用:
```ocaml
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);
}
```
运行结果为:
```
starting up ...
hello from OCaml
acquiring ...
acquired
```
|