From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,126ce244c524526b X-Google-Attributes: gid103376,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!feeder1-2.proxad.net!proxad.net!feeder2-2.proxad.net!newsfeed.arcor.de!newsspool2.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Tasking issues Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <1186851804.567302.223160@q4g2000prc.googlegroups.com> Date: Sat, 11 Aug 2007 20:42:23 +0200 Message-ID: NNTP-Posting-Date: 11 Aug 2007 20:42:16 CEST NNTP-Posting-Host: 4d98fa05.newsspool4.arcor-online.net X-Trace: DXC=nheJN:7GbH=U`5g[@c]@J14IUK;`;jgYdFJf6Be3jdGiH_\< X-Complaints-To: usenet-abuse@arcor.de Xref: g2news2.google.com comp.lang.ada:1401 Date: 2007-08-11T20:42:16+02:00 List-Id: On Sat, 11 Aug 2007 10:03:24 -0700, shaunpatterson@gmail.com wrote: > I'm having trouble with tasking in Ada. I'm used to working with > pthreads in C/C++... and I'm finding tasks to be somewhat different/annoying. > > My basic problem is I want to have 2 threads in my program. Is that a problem? > One thread sits in the background and reads in messages, > dispatches them, etc and the other thread reads off a queue > and sends out messages when they are available. Queue of what? Of messages? > As an analogy, let's assume my background task just got > input from the user (simulating the socket read) and the other > task just printed out stuff. > > Something like > > procedure main is > begin This is an error > task get_name; > task print_something; > > task body get_name is > Name : String (1..25); > Last : Integer; > begin > loop > Get_Line (Name, Last); > end loop; > end get_name; > > task body print_something is > begin > loop > Put_Line ("blah..."); > end loop; > end print_something; > > begin --- main > > loop; This is also an error > null; > end loop; You don't need a loop here. Your program will never end without looping because the tasks do not. > end main; > > Of course, this doesn't work as I'd expect. You didn't say what you expect. > Is there a way to "timeout" the > first get_name thread... so the OS only waits on that thread for a > short period of time to allow the other threads to do their business? and then go > back to the thread? I don't understand, tasks are subject of scheduling and time sharing. They are switched even if they have something to do. If you want to stop print_something when get_name gets an input, you will need some communication between tasks. You can use a protected object for that or rendezvous. For example: with Ada.Text_IO; use Ada.Text_IO; procedure Main is task Get_Name; task Print_Something is entry Got_Name (Name : String); -- Got user input entry Completed; -- Get_Name is done entry Shut_Down; -- On exit end Print_Something; task body Get_Name is Name : String (1..25); Last : Integer; begin loop select Print_Something.Completed; exit; then abort Get_Line (Name, Last); end select; Print_Something.Got_Name (Name (1..Last)); end loop; Put_Line ("Get_Name is down"); end Get_Name; task body Print_Something is begin loop select accept Got_Name (Name : String) do Put_Line ("Here is the name:" & Name); end Got_Name; delay 1.0; -- Just to make it visible among blah's or accept Shut_Down; Put_Line ("Print_Something is going down"); exit; else Put_Line ("blah..."); end select; end loop; accept Completed; Put_Line ("Print_Something is down"); end Print_Something; begin delay 10.0; -- We don't want to have it endlessly Print_Something.Shut_Down; -- Kill them all end Main; Here Get_Name reads user input and then passes it to Print_Something. Print_Something prints either "blah..." or what Get_Name gave it. The affairs are completed when Print_Something receives Shut_Down. It waits a bit until Get_Name tell it that it is finished too. Note that Get_Line in Get_Name is placed in an asynchronous transfer of control select. See ARM 9.7.4. It waits for Print_Something.Completed while reading the line. Then the former triggers, it aborts reading and exits the loop and the task with it. And, well, you don't need main. You can move Get_Name stuff to main. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de