From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by yquem.inria.fr (Postfix) with ESMTP id 2C79FBC37 for ; Mon, 26 Oct 2009 20:06:21 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtQAADOQ5UrRVd/BmGdsb2JhbACPboFxiRs/AQEBAQEGCwwHE61DgTuFS4hoAQMDBYQ6BA X-IronPort-AV: E=Sophos;i="4.44,627,1249250400"; d="scan'208";a="35641561" Received: from mail-iw0-f193.google.com ([209.85.223.193]) by mail2-smtp-roc.national.inria.fr with ESMTP; 26 Oct 2009 20:06:20 +0100 Received: by iwn31 with SMTP id 31so6503397iwn.0 for ; Mon, 26 Oct 2009 12:06:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=JC97HQUa9gQ5qiTdoLkPlzf35OpGkdqPuwX8qF1fkSY=; b=apdEovD3qu+B/RL1AOAkJaOUSV1x/xxvDjSCEkKa1MURyrb7VQC7uio1tlj1j+efDL Hl2Vfnw1926FMCeV3OHoaKC0+wSK2X1PbQBZ5hBaTStgZSPqZPAGc6JOK70F1cxpjRPv fDQ8x8OPek1O8TgIyY444ygZNzuMz75t4n094= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; b=ChdGEsQa7mkQQmqmhOtjRrNbw5VmrgXBWG22WxhHf+0xfNtQ+U91ApJq20sO04YkDw y8s2lZjSSu60q8dDoEtfYkjHFcMK5D43GqlhnenH6lIMmarZ7mRS+0+0aI/uY5D0xia0 OKFENdfYb2nwGWYtYp/hB/6s78HwK3pPxFo/A= MIME-Version: 1.0 Received: by 10.231.9.33 with SMTP id j33mr13050928ibj.37.1256583979605; Mon, 26 Oct 2009 12:06:19 -0700 (PDT) In-Reply-To: <9d3ec8300910261136w3cee8329od4b0a02365cde8db@mail.gmail.com> References: <9d3ec8300910261136w3cee8329od4b0a02365cde8db@mail.gmail.com> Date: Mon, 26 Oct 2009 12:06:18 -0700 Message-ID: Subject: Re: [Caml-list] threads, signals, and timeout From: yoann padioleau To: Till Varoquaux Cc: caml-list@inria.fr Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Spam: no; 0.00; model:01 invocation:01 computations:01 computations:01 ocaml:01 ocaml:01 scheduler:01 opengroup:01 onlinepubs:01 mli:01 ocamlc:01 -thread:01 prerr:01 endline:01 printf:01 On Mon, Oct 26, 2009 at 11:36 AM, Till Varoquaux wrot= e: > 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. Bu= t 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 wro= te: >> 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 s= econd :( >> >> >> (* >> ocamlc -g -thread unix.cma threads.cma signals_and_threads.ml >> *) >> >> exception Timeout >> >> let mytid () =3D >> =A0let t =3D Thread.self () in >> =A0let i =3D Thread.id t in >> =A0i >> >> let set_timeout () =3D >> >> =A0Sys.set_signal Sys.sigalrm >> =A0 =A0(Sys.Signal_handle (fun _ -> >> =A0 =A0 =A0prerr_endline "Time is up!"; >> =A0 =A0 =A0print_string (Printf.sprintf "id: %d\n" (mytid())); >> =A0 =A0 =A0raise Timeout >> =A0 =A0)); >> >> =A0ignore(Unix.alarm 1); >> =A0() >> >> >> let main =3D >> =A0let t1 =3D >> =A0 =A0Thread.create (fun () -> >> =A0 =A0 =A0set_timeout (); >> =A0 =A0 =A0print_string (Printf.sprintf "t1 id: %d\n" (mytid())); >> >> =A0 =A0 =A0let xs =3D [1;2;3] in >> =A0 =A0 =A0while(true) do >> =A0 =A0 =A0 =A0let _ =3D List.map (fun x -> x + 1) xs in >> =A0 =A0 =A0 =A0() >> =A0 =A0 =A0done; >> =A0 =A0 =A0() >> =A0 =A0) () >> =A0in >> >> =A0let t2 =3D >> =A0 =A0Thread.create (fun () -> >> =A0 =A0 =A0set_timeout (); >> =A0 =A0 =A0print_string (Printf.sprintf "t2 id: %d\n" (mytid())); >> >> =A0 =A0 =A0let xs =3D [1;2;3] in >> =A0 =A0 =A0while(true) do >> =A0 =A0 =A0 =A0let _ =3D List.map (fun x -> x + 1) xs in >> =A0 =A0 =A0 =A0() >> =A0 =A0 =A0done; >> =A0 =A0 =A0() >> =A0 =A0) () >> =A0in >> =A0Thread.join t1; >> =A0Thread.join t2; >> =A0() >> >> ------------------ >> >> >> >> >> 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 >> .... > >> _______________________________________________ >> 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 >> >