Version française
Home     About     Download     Resources     Contact us    
Browse thread
threads, signals, and timeout
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: yoann padioleau <pad.aryx@g...>
Subject: Re: [Caml-list] threads, signals, and timeout
On Mon, Oct 26, 2009 at 11:36 AM, Till Varoquaux <till@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/000095399/functions/alarm.html
> [2]: http://ocsigen.org/lwt/
> On Mon, Oct 26, 2009 at 2:08 PM, yoann padioleau <pad.aryx@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
>>
>