Content-Type: multipart/alternative; boundary=e0cb4e887ee93c20ad048def8867
X-Spam: no; 0.00; sigterm:01 model:01 sigterm:01 printf:01 sig:01 printf:01 ocamlfind:01 ocamlopt:01 -linkpkg:01 -thread:01 -package:01 model:01 sig:01 ocamlfind:01 ocamlopt:01
X-Attachments: cset="UTF-8" cset="UTF-8"
--e0cb4e887ee93c20ad048def8867
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
I'm writing an application in which some threads do their job, communicatin=
g
with the Concurrent Cell library . In
this context I decided to avoid 1) the multiprocess model, for the sake of
simplicity and 2) libraries like Lwt, because the threads use many external
and non lwt-aware libraries.
When the process receives a SIGTERM, I want to smoothly kill the process. T=
o
do this I send (in the signal handler) a message to all the threads, and th=
e
main thread waits (Thread.join) for the other worker to finish. Then the
main thread exits. To do this I install a signal handler in the main thread
(Sys.set_signal)
I found a strange behavior: when the process receives the SIGTERM, the
programs terminates with the exception Unix.Unix_error(11, "select", "").
I was able to remove all the noise and obtain a minimal program exposing
the behavior. Here it is:
$ cat thread_test.ml
open Printf;;
Random.self_init ();;
let do_something id () =3D
let _ =3D Thread.sigmask Unix.SIG_SETMASK [15] in
while true
do
Thread.delay (1.0 +. (Random.float 1.0));
printf "Thread %d\n%!" id
done
;;
(* MAIN THREAD FROM HERE *)
let kill_handler _ =3D printf "Signal caught\n%!";;
Sys.set_signal 15 (Sys.Signal_handle kill_handler);;
ignore (Thread.create (do_something 1) ());;
ignore (Thread.create (do_something 2) ());;
ignore (Thread.create (do_something 3) ());;
while true
do
Thread.delay 5.0; (* Unix.sleep 5 WORKS! *)
printf "Main Thread\n%!";
done;;
The process should (at least I think) catch the SIGTERM signal and continue
without problems. Instead the result is this:
$ ocamlfind ocamlopt -linkpkg -thread -package threads thread_test.ml -o
thread_test
$ ./thread_test
Thread 1
Thread 2
Thread 3
Thread 1
Thread 2
Thread 3
Thread 1
Thread 2
Main Thread
Thread 1
Thread 3
Thread 2
Thread 3
Thread 1
Thread 2
Thread 1
Thread 3
Signal caught <--- *in* *another shell*: $ kill -15 PID
Fatal error: exception Unix.Unix_error(11, "select", "")
The exception is raised by the Thread.delay function present in the loop of
the main thread. Note that if I use Unix.sleep 5 instead of Thread.delay 5.=
0
the program runs as expected.
Any ideas?
Best regards,
--=20
Paolo =E2=A0=A0=E2=A0=B5
--e0cb4e887ee93c20ad048def8867
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
I'm writing an application in which some threads do their job, communic=
ating with the Concurrent Cell library. In this context I decided to avoid 1) the =
multiprocess model, for the sake of simplicity and 2) libraries like Lwt, b=
ecause the threads use many external and non lwt-aware libraries.
When the process receives a SIGTERM, I want to=C2=A0smoothly=
kill the process. To do this I send (in the signal handler) a message to a=
ll the threads, and the main thread waits (Thread.join) for the other worke=
r to finish. Then the main thread exits. To do this I install a signal hand=
ler in the main thread (Sys.set_signal)
I found a strange=C2=A0behavior: when the process recei=
ves the SIGTERM, the programs terminates with the exception=C2=A0Unix.Unix_=
error(11, "select", "").
I was=
able to remove all the noise and obtain a minimal program exposing the=C2=
=A0behavior. Here it is:
open Printf;;
Random.self_init ();;
let do_something id () =3D
=C2=
=A0=C2=A0let _ =3D Thread.sigmask Unix.SIG_SETMASK [15] in
=C2=A0=C2=A0while true
=C2=A0=C2=A0do
=C2=A0=C2=A0 =C2=A0printf "Thread %d\n%!" id ;;
(* MAIN THREAD FROM HERE *)<=
/font>
let kill_handler _ =3D printf "Signal=C2=A0caught\n%!"=
;;;
Sys.set_signal 15 (Sys.Signal_handle kill_handle=
r);;
ignore (Thread.create (do_something 1) ());;
ignore (Thread.create (do_something 2) ());;
ignore (=
Thread.create (do_something 3) ());;
while true
do
=C2=A0=C2=A0Thread.delay 5.0; (* Unix.sleep 5 WORKS! *)
=C2=A0=C2=A0printf "Main Thread\n%!";
done;;
The process shou=
ld (at least I think) catch the SIGTERM signal and continue without problem=
s. Instead the result is this:
$=C2=A0ocamlfind ocamlopt -linkpkg -thread -packag=
e threads thread_test.ml -o thread_te=
st
$ ./thread_test=C2=A0
Thread 1
Thread 2
Thread 3
Thread 1
Thread 2
Thread 3
Thread 1
Thread 2
Main Thread
Thread 1
Thread 3=
Thread 2
Thread 3
Thread 1
Thread 2
Thread 1
Thread 3
=
Signal=C2=A0caught=C2=A0 <--- in another shell: $ kill -15=
=C2=A0PID
Fatal error: exception Unix.Unix_error(11, "s=
elect", "")
The exception is raised by the Thread.delay funct=
ion present in the loop of the main thread. Note that if I use Unix.sleep 5=
instead of Thread.delay 5.0 the program runs as expected.
Any ideas?
Best regards,
--=C2=A0=
Paolo =E2=A0=A0=E2=A0=B5
--e0cb4e887ee93c20ad048def8867--