[Caml-list] threads, signals, and timeout

2009-10-26 Thread yoann padioleau
Hi,

I would like to create different threads where each thread do some
computation and are subject to different
timeout. Without threads I usually use Unix.alarm with a SIGALARM
handler that just raise a Timeout exception
and everything works fine, but when I try to do something similar with
threads it does not work
because apparently the Unix.alarm done in one thread override the
Unix.alarm done in another
thread. I had a look at thread.mli but was not able to find anything
related to timeout.
Is there a way to have multiple timeout and multiple threads at the same time ?

Here is a program that unforunately get the first timeout, but not the second :(


(*
ocamlc -g -thread unix.cma threads.cma signals_and_threads.ml
*)

exception Timeout

let mytid () =
  let t = Thread.self () in
  let i = Thread.id t in
  i

let set_timeout () =

  Sys.set_signal Sys.sigalrm
(Sys.Signal_handle (fun _ -
  prerr_endline Time is up!;
  print_string (Printf.sprintf id: %d\n (mytid()));
  raise Timeout
));

  ignore(Unix.alarm 1);
  ()


let main =
  let t1 =
Thread.create (fun () -
  set_timeout ();
  print_string (Printf.sprintf t1 id: %d\n (mytid()));

  let xs = [1;2;3] in
  while(true) do
let _ = List.map (fun x - x + 1) xs in
()
  done;
  ()
) ()
  in

  let t2 =
Thread.create (fun () -
  set_timeout ();
  print_string (Printf.sprintf t2 id: %d\n (mytid()));

  let xs = [1;2;3] in
  while(true) do
let _ = List.map (fun x - x + 1) xs in
()
  done;
  ()
) ()
  in
  Thread.join t1;
  Thread.join t2;
  ()

--




Here is the output
Time is up!
t2 id: 2
t1 id: 1
id: 1
Thread 1 killed on uncaught exception Signals_and_threads.Timeout
 the program loops, meaning the second thread never received its timeout

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


Re: [Caml-list] threads, signals, and timeout

2009-10-26 Thread yoann padioleau
On Mon, Oct 26, 2009 at 11:36 AM, Till Varoquaux t...@pps.jussieu.fr wrote:
 You'd have the same problem in any other programming language; this is
 due to the underlying POSIX model.
 The POSIX standard mentions that alarms are global to the process [1].

  There were two possible choices for alarm generation in
 multi-threaded applications: generation for the calling thread or
 generation for the process. The first option would not have been
 particularly useful since the alarm state is maintained on a
 per-process basis and the alarm that is established by the last
 invocation of alarm() is the only one that would be active.

I've seen that that there are other C APIs for timers: setitimer,
create_timer, ... are they all subject to the same limitations ?

 As a general matter mixing signals and threads is a thorny issue under
 unix; you should avoid doing so unless you have a good grasp of what
 is going to happen. Having a global timer thread that kills timed-out
 threads would be possible but seems very painful.

I dont want to kill them. I want to deliver timeout exceptions to those
threads, and each of those threads should be able to react differently
to those timeouts.

 If you give us more
 information on what you are trying to achieve (eg your computations
 threads are crunshing numbers in a tight loop or you are performing io
 etc...) we might be able to guide you.

I want to write a toy program that uses threads and timeouts in an
easy way. Those
threads may make heavy use of CPU or IO, I don't know. I just want
an easy API for thread and timeout.

 Here is a quick run down of my
 flawed and partial understand of the world:

 For heavy computations threads will not help you. I am sure you are
 aware of this but there never is more than one ocaml thread running at
 the same time.

To be honest, the problem I have to solve is not in OCaml, but I thought
OCaml programmers would give better answers than C programmers :)

I find it wierd that using timeout with process is easy, and using
timeouts with threads
is not.  Apparently on google they say a usual technique is to have a
master thread
which handles all the signals, with all the other threads blocking them. But
it would still require this master thread  juggling with multiple
timeouts requests and deliveries, and then to deliver manually some
signals to the specific thread (with
pthread_kill ?). I don't want to write my own scheduler.
Those things should be handled at kernel level;
the kernel should know about threads, and should be able to deliver
signals to the thread that requested them. Maybe the new Linux
thread library (NPTL) can do that ?


 If you can fork and collect the resulting data through
 pipes or shared memory you should be able to get a noticeable
 performance boost. There have been countless posts on the subject; I
 am too lazy to google them up.

 I/O is a very different beast and you are probably better of with an
 asynchronous framework. Luckily for you Ocaml has a pretty good one
 already available [2]

 Till

 [1]: http://www.opengroup.org/onlinepubs/95399/functions/alarm.html
 [2]: http://ocsigen.org/lwt/
 On Mon, Oct 26, 2009 at 2:08 PM, yoann padioleau pad.a...@gmail.com wrote:
 Hi,

 I would like to create different threads where each thread do some
 computation and are subject to different
 timeout. Without threads I usually use Unix.alarm with a SIGALARM
 handler that just raise a Timeout exception
 and everything works fine, but when I try to do something similar with
 threads it does not work
 because apparently the Unix.alarm done in one thread override the
 Unix.alarm done in another
 thread. I had a look at thread.mli but was not able to find anything
 related to timeout.
 Is there a way to have multiple timeout and multiple threads at the same 
 time ?

 Here is a program that unforunately get the first timeout, but not the 
 second :(


 (*
 ocamlc -g -thread unix.cma threads.cma signals_and_threads.ml
 *)

 exception Timeout

 let mytid () =
  let t = Thread.self () in
  let i = Thread.id t in
  i

 let set_timeout () =

  Sys.set_signal Sys.sigalrm
    (Sys.Signal_handle (fun _ -
      prerr_endline Time is up!;
      print_string (Printf.sprintf id: %d\n (mytid()));
      raise Timeout
    ));

  ignore(Unix.alarm 1);
  ()


 let main =
  let t1 =
    Thread.create (fun () -
      set_timeout ();
      print_string (Printf.sprintf t1 id: %d\n (mytid()));

      let xs = [1;2;3] in
      while(true) do
        let _ = List.map (fun x - x + 1) xs in
        ()
      done;
      ()
    ) ()
  in

  let t2 =
    Thread.create (fun () -
      set_timeout ();
      print_string (Printf.sprintf t2 id: %d\n (mytid()));

      let xs = [1;2;3] in
      while(true) do
        let _ = List.map (fun x - x + 1) xs in
        ()
      done;
      ()
    ) ()
  in
  Thread.join t1;
  Thread.join t2;
  ()

 --




 Here is the output
 Time is up!
 t2 id: 2
 t1 id: 1
 id: 1
 Thread 1 killed on 

Re: [Caml-list] threads, signals, and timeout

2009-10-26 Thread Gerd Stolpmann

Am Montag, den 26.10.2009, 12:06 -0700 schrieb yoann padioleau:
 On Mon, Oct 26, 2009 at 11:36 AM, Till Varoquaux t...@pps.jussieu.fr wrote:
  You'd have the same problem in any other programming language; this is
  due to the underlying POSIX model.
  The POSIX standard mentions that alarms are global to the process [1].
 
   There were two possible choices for alarm generation in
  multi-threaded applications: generation for the calling thread or
  generation for the process. The first option would not have been
  particularly useful since the alarm state is maintained on a
  per-process basis and the alarm that is established by the last
  invocation of alarm() is the only one that would be active.
 
 I've seen that that there are other C APIs for timers: setitimer,
 create_timer, ... are they all subject to the same limitations ?
 
  As a general matter mixing signals and threads is a thorny issue under
  unix; you should avoid doing so unless you have a good grasp of what
  is going to happen. Having a global timer thread that kills timed-out
  threads would be possible but seems very painful.
 
 I dont want to kill them. I want to deliver timeout exceptions to those
 threads, and each of those threads should be able to react differently
 to those timeouts.
 
  If you give us more
  information on what you are trying to achieve (eg your computations
  threads are crunshing numbers in a tight loop or you are performing io
  etc...) we might be able to guide you.
 
 I want to write a toy program that uses threads and timeouts in an
 easy way. Those
 threads may make heavy use of CPU or IO, I don't know. I just want
 an easy API for thread and timeout.
 
  Here is a quick run down of my
  flawed and partial understand of the world:
 
  For heavy computations threads will not help you. I am sure you are
  aware of this but there never is more than one ocaml thread running at
  the same time.
 
 To be honest, the problem I have to solve is not in OCaml, but I thought
 OCaml programmers would give better answers than C programmers :)
 
 I find it wierd that using timeout with process is easy, and using
 timeouts with threads
 is not.  Apparently on google they say a usual technique is to have a
 master thread
 which handles all the signals, with all the other threads blocking them. But
 it would still require this master thread  juggling with multiple
 timeouts requests and deliveries, and then to deliver manually some
 signals to the specific thread (with
 pthread_kill ?). I don't want to write my own scheduler.
 Those things should be handled at kernel level;
 the kernel should know about threads, and should be able to deliver
 signals to the thread that requested them. Maybe the new Linux
 thread library (NPTL) can do that ?

Till gave already a quite good answer. I think your assumption is
already wrong that using timeouts with processes is easy. It's only
easy as long you don't care about race conditions and subtle problems of
signals (e.g. that two pending signals are merged by the kernel). Most
likely you get a program that works 99% of the time, and fails (hangs,
or loops, or misses signals) 1% of the time. Signals are really
low-level.

Combining threads and signals leads to numerous implementation problems.
Both the threads and signals API define primitives for synchronization
(e.g. mutexes for threads, and masks for signals). As signals can be
generated at any time, there is no control about the state of the
thread-level synchronization objects: When the signal handler is
entered, you don't know whether a thread (either the thread the handler
is running in, or some other) has locked the mutex or not (given that
the signal handler accesses some shared data). Even worse, you cannot
simply wait in the handler until the mutex is free again - this could be
a deadlock. Essentially, you cannot synchronize data access of a signal
handler and of threads - it's conceptually impossible. Think like this:
A single thread is executed sequentially, and the primitives for
synchronizing several threads rely on that. Signals, however, allow it
to spontaneously interrupt the sequential execution, as if one thread
would be many. That breaks assumptions of multi-threading.

That's the background why POSIX chose not to define a per-thread signal
API. There are no per-thread timers, and you need to write your own mini
scheduler.

Gerd

 
 
  If you can fork and collect the resulting data through
  pipes or shared memory you should be able to get a noticeable
  performance boost. There have been countless posts on the subject; I
  am too lazy to google them up.
 
  I/O is a very different beast and you are probably better of with an
  asynchronous framework. Luckily for you Ocaml has a pretty good one
  already available [2]
 
  Till
 
  [1]: http://www.opengroup.org/onlinepubs/95399/functions/alarm.html
  [2]: http://ocsigen.org/lwt/
  On Mon, Oct 26, 2009 at 2:08 PM, yoann padioleau pad.a...@gmail.com wrote:
  

Re: [Caml-list] threads, signals, and timeout

2009-10-26 Thread Philippe Wang
Considering that posix signals are not real-time *anyway*, using them
to programme specific treatments per-thread is hmmm... say a nightmare
! Plus I don't quite see how you could eventually have a non-broken
implementation. Gerd Stolpmann emphasized it if I understood well.

One solution would be to use state variables to check every once in a while.

Or maybe to use fairthreads instead, but I guess that the problem is
actually much more complicated than just that.

Well, I thought I had more interesting things to say. I was wrong,
then just my two cents.
Anyways, good luck!

Cheers,

Philippe Wang


On Mon, Oct 26, 2009 at 7:08 PM, yoann padioleau pad.a...@gmail.com wrote:
 Hi,

 I would like to create different threads where each thread do some
 computation and are subject to different
 timeout. Without threads I usually use Unix.alarm with a SIGALARM
 handler that just raise a Timeout exception
 and everything works fine, but when I try to do something similar with
 threads it does not work
 because apparently the Unix.alarm done in one thread override the
 Unix.alarm done in another
 thread. I had a look at thread.mli but was not able to find anything
 related to timeout.
 Is there a way to have multiple timeout and multiple threads at the same time 
 ?

 Here is a program that unforunately get the first timeout, but not the second 
 :(


 (*
 ocamlc -g -thread unix.cma threads.cma signals_and_threads.ml
 *)

 exception Timeout

 let mytid () =
  let t = Thread.self () in
  let i = Thread.id t in
  i

 let set_timeout () =

  Sys.set_signal Sys.sigalrm
(Sys.Signal_handle (fun _ -
  prerr_endline Time is up!;
  print_string (Printf.sprintf id: %d\n (mytid()));
  raise Timeout
));

  ignore(Unix.alarm 1);
  ()


 let main =
  let t1 =
Thread.create (fun () -
  set_timeout ();
  print_string (Printf.sprintf t1 id: %d\n (mytid()));

  let xs = [1;2;3] in
  while(true) do
let _ = List.map (fun x - x + 1) xs in
()
  done;
  ()
) ()
  in

  let t2 =
Thread.create (fun () -
  set_timeout ();
  print_string (Printf.sprintf t2 id: %d\n (mytid()));

  let xs = [1;2;3] in
  while(true) do
let _ = List.map (fun x - x + 1) xs in
()
  done;
  ()
) ()
  in
  Thread.join t1;
  Thread.join t2;
  ()

 --




 Here is the output
 Time is up!
 t2 id: 2
 t1 id: 1
 id: 1
 Thread 1 killed on uncaught exception Signals_and_threads.Timeout
  the program loops, meaning the second thread never received its timeout


___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs