From d5de65fdb1802cdf498d65d93397f290813c377c Mon Sep 17 00:00:00 2001 From: muqiuhan Date: Tue, 9 Sep 2025 06:17:00 +0000 Subject: deploy: 9665097f0fa0dae9f92123fac54d26c0818758a5 --- 2023/08/15/poll-error-attribute-in-OCaml/index.html | 1 - .../index.html" | 1 - .../index.html" | 6 ++++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to '2023/08') diff --git a/2023/08/15/poll-error-attribute-in-OCaml/index.html b/2023/08/15/poll-error-attribute-in-OCaml/index.html index a31bde90..d48bc2eb 100644 --- a/2023/08/15/poll-error-attribute-in-OCaml/index.html +++ b/2023/08/15/poll-error-attribute-in-OCaml/index.html @@ -197,7 +197,6 @@

OCaml 编译器提供了一个名为 [@poll error] 的annotation,可以在函数中使用它来确保该函数不包含safe point。

所以通过使用 [@poll error] 就可以创建在Domain内原子性执行的函数,也就是说,基于此特性可以实现单个Domain内线程安全的数据结构,例如 thread-table 便是使用这个特性实现的 Hash Table。可以看看它的 add 函数的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let[@poll error] add_atomically t buckets n i before after =
t.rehash = 0 && buckets == t.buckets
&& before == Array.unsafe_get buckets i
&& begin
Array.unsafe_set buckets i after;
let length = t.length + 1 in
t.length <- length;
if n < length && n < max_buckets_div_2 then t.rehash <- n * 2;
true
end

let rec add t k' v' =
let h = Mix.int k' in
maybe_rehash t;
let buckets = t.buckets in
let n = Array.length buckets in
let i = h land (n - 1) in
let before = Array.unsafe_get buckets i in
let after = Cons (k', v', before) in
if not (add_atomically t buckets n i before after) then add t k' v'
-

相比使用 Stdlib.Mutex,这种无锁实现会有更好的性能(特别是对于只读操作),并且还允许例如信号处理之类的上下文操作。

diff --git "a/2023/08/15/tick-thread\345\234\250Multicore-OCaml\344\270\255\347\232\204\344\275\234\347\224\250/index.html" "b/2023/08/15/tick-thread\345\234\250Multicore-OCaml\344\270\255\347\232\204\344\275\234\347\224\250/index.html" index fa346797..decea234 100644 --- "a/2023/08/15/tick-thread\345\234\250Multicore-OCaml\344\270\255\347\232\204\344\275\234\347\224\250/index.html" +++ "b/2023/08/15/tick-thread\345\234\250Multicore-OCaml\344\270\255\347\232\204\344\275\234\347\224\250/index.html" @@ -194,7 +194,6 @@

Multicore OCaml的程序在启动时会运行一个 tick thread,其实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* The tick thread: posts a SIGPREEMPTION signal periodically */

static void * caml_thread_tick(void * arg)
{
struct timeval timeout;
sigset_t mask;

/* Block all signals so that we don't try to execute an OCaml signal handler*/
sigfillset(&mask);
pthread_sigmask(SIG_BLOCK, &mask, NULL);
while(! caml_tick_thread_stop) {
/* select() seems to be the most efficient way to suspend the
thread for sub-second intervals */
timeout.tv_sec = 0;
timeout.tv_usec = Thread_timeout * 1000;
select(0, NULL, NULL, NULL, &timeout);
/* The preemption signal should never cause a callback, so don't
go through caml_handle_signal(), just record signal delivery via
caml_record_signal(). */
caml_record_signal(SIGPREEMPTION);
}
return NULL;
}
-

这是因为Multicore OCaml的GC目前需要一个进程(或一个Domain)中的所有线程一起参与以避免并发访问。如果一个线程在system call上被阻塞,那么整个Domain就会被卡住,直到该线程可以参与当前的垃圾收集。为了避免这个问题,tick 线程可以代替被阻塞的线程执行垃圾收集操作。

diff --git "a/2023/08/27/\344\272\214\351\233\266\344\272\214\344\270\211\345\271\264\345\205\253\346\234\210\344\272\214\345\215\201\344\270\203\346\227\245/index.html" "b/2023/08/27/\344\272\214\351\233\266\344\272\214\344\270\211\345\271\264\345\205\253\346\234\210\344\272\214\345\215\201\344\270\203\346\227\245/index.html" index 0a1837e8..3efbd1bf 100644 --- "a/2023/08/27/\344\272\214\351\233\266\344\272\214\344\270\211\345\271\264\345\205\253\346\234\210\344\272\214\345\215\201\344\270\203\346\227\245/index.html" +++ "b/2023/08/27/\344\272\214\351\233\266\344\272\214\344\270\211\345\271\264\345\205\253\346\234\210\344\272\214\345\215\201\344\270\203\346\227\245/index.html" @@ -184,9 +184,11 @@
-

我从失去家人的那一刻就坠入了一个朦胧而美丽的梦,梦境没有主人,我是被梦境所留下的,永远不愿醒来的旅人。
我足不出户,一直缩在一方小世界里面,我用了无数的理由和所有人说我的生活态度,其实勇敢的人根本不需要理由就能走出去,只有懦弱的人会用各种理由说服自己退缩

+

我从失去家人的那一刻就坠入了一个朦胧而美丽的梦,梦境没有主人,我是被梦境所留下的,永远不愿醒来的旅人。
+我足不出户,一直缩在一方小世界里面,我用了无数的理由和所有人说我的生活态度,其实勇敢的人根本不需要理由就能走出去,只有懦弱的人会用各种理由说服自己退缩

请以我为戒,大胆往前走,走到灯火通明。

-

何须纵酒方能舞翩迁,
赤诚相见时便是少年。

+

何须纵酒方能舞翩迁,
+赤诚相见时便是少年。

-- cgit v1.2.3