【发布时间】:2013-05-15 05:24:48
【问题描述】:
我已经根据http://www.linux-nantes.org/~fmonnier/ocaml/ocaml-wrapping-c.php 的指南为 CZMQ 编写了一些 OCaml 绑定,这些绑定似乎运行良好。例如这里的 zstr_send:
CAMLprim value
caml_zstr_send(value socket_val, value string_val)
{
CAMLparam2 (socket_val, string_val);
void *sock = CAML_CZMQ_zsocket_val(socket_val);
char *string = String_val(string_val);
int rc = zstr_send(sock, string);
CAMLreturn (Val_int(rc));
}
我可以在我的大部分代码中使用这些绑定发送和接收消息。但是,我有一个场景,我想在信号处理程序内部进行发送和接收,直到在其他代码的后台进行消息传递。举个简化的例子:
open ZMQ
exception SocketBindFailure
let bg_ctx = zctx_new ();;
let pub_sock = zsocket_new bg_ctx ZMQ_PUB;;
let handler _ =
print_endline "enter handler";
print_endline (string_of_int (zstr_send pub_sock "hello"));
print_endline "end handler";
;;
let () =
(try (
(* bind pub socket *)
let rc = zsocket_bind pub_sock "tcp://*:5556" in
if (rc < 0) then ( raise SocketBindFailure );
Sys.set_signal
Sys.sigalrm
(Sys.Signal_handle handler);
ignore
(Unix.setitimer
Unix.ITIMER_REAL
{ Unix.it_interval = 0.01 ; Unix.it_value = 0.01 });
(* do some work *)
)
with
| SocketBindFailure -> raise SocketBindFailure)
;;
从顶层开始,输出失败:
enter handler
0
end handler
Fatal error: exception Sys_blocked_io
与上面的 OCaml 类似的 C 代码可以正常工作。 OCaml 在导致此异常的方程式中添加了什么?
【问题讨论】:
-
一般来说,在我审核代码时,从信号处理程序中调用任何例程都是一个危险信号。原因多种多样,但要点是您必须 100% 确定例程是异步安全的。 See this for more details.
-
我不能告诉你为什么你会得到这个异常,只是说你已经在从处理程序中尝试 IO 处于危险的基础上,无论是 C 还是 OCaml。我相信上面的链接为您提供了一些安全记录信号处理程序调用的方法。
-
感谢您提供的信息,戴夫。那我会采取不同的方法。
-
也许你的 OCaml 代码中有一个
Unix.set_nonblock()。众所周知,OCaml 在尝试任何阻塞 I/O 时通常会生成Fatal error: exception Sys_blocked_io。 -
能否也给我们C代码?