<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix"><font face="Helvetica, Arial,
        sans-serif">Hey, thanks Kevin!  Very nicely done.<br>
        <br>
        --Tommy Butler<br>
        <br>
        On 01/10/2014 02:15 AM, kevin wrote:<br>
      </font></div>
    <blockquote cite="mid:52CFAC05.4080305@pwhome.com" type="cite"><font
        face="Helvetica, Arial, sans-serif">On 01/05/2014 12:51 PM,
        Tommy Butler wrote:
        <br>
      </font>
      <blockquote type="cite"><font face="Helvetica, Arial, sans-serif">Just
          for fun, I thought I'd post this to the list.  It's a
          discussion on
          <br>
          perlmonks about why the reference code (threaded version)
          doesn't seem
          <br>
          to have large gains over the non-threaded version.  If you are
          also
          <br>
          using concurrency in your hackathon code to try to speed
          things up, it
          <br>
          could be a matter of either or both of: you don't need it
          (really you
          <br>
          may not), or you're doing it wrong.
          <br>
        </font>
        <font face="Helvetica, Arial, sans-serif"><br>
          <a class="moz-txt-link-freetext" href="http://perlmonks.org/?node_id=1069338">http://perlmonks.org/?node_id=1069338</a>
          <br>
        </font></blockquote>
      <font face="Helvetica, Arial, sans-serif"><br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        Tommy,
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        Sorry I'm slow, but I read the post and thought I'd give you
        this example. It's quite probable that you no longer need this
        as you have everything working, but perhaps it'll help someone.
        I've been meaning to post this to Perl Monks, but haven't gotten
        around to it.
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        I remember wanting to do some things with threads some time back
        and having a devil of a time trying to find a simple example
        that showed everything I needed to do. So I cobbled this
        together.
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        I think this has the "architecture" you were looking for, i.e. a
        parent in control, the children picking up tasks as fast as they
        could do them, so there's no real gate keeper. As with so many
        things, picking the right values for your task with number of
        children & number of items in the input queue is up to you.
        :) I think it's reasonably well documented, considering it's a
        test example, which I tend not to document at all, much to my
        detriment later. ;) It's sort of put together much in the manner
        I would have written back in the day when I used IPCs in C on a
        weekly basis.
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        HTH,
        <br>
        Kevin
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        ===cut===
        <br>
        #!/usr/bin/perl;
        <br>
        #
        <br>
        # Example program for threads and queues.
        <br>
        #
        <br>
        # The parent will create an input queue for work to be done. It
        will be
        <br>
        # a number of tasks ($num_tasks). To do the work, it will create
        a number
        <br>
        # of children ($num_children) to do the work. Because this is a
        simple
        <br>
        # example, we'll just put a set of random numbers in the queue
        (from
        <br>
        # 1 to $task_time) for the children to work on. By convention,
        they know
        <br>
        # to sleep that number of seconds then consider the work done
        and return a
        <br>
        # "result" to the parent, before grabbing the next task to be
        done.
        <br>
        # Once all the tasks are done, they end ... as does the parent.
        <br>
        #
        <br>
        # In real life, the parent could add more work, the children
        could sleep
        <br>
        # until a specific command was given, etc.
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        use strict;
        <br>
        use warnings;
        <br>
        use threads qw(stringify);
        <br>
        use Thread::Queue;
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        my $num_children = 3;
        <br>
        my $num_tasks = 10;
        <br>
        my $task_time = 5;
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        # create communication queues
        <br>
        my $inputq = Thread::Queue->new();
        <br>
        my $outputq = Thread::Queue->new();
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        # queue up tasks
        <br>
        for (1 .. $num_tasks)
        <br>
        {
        <br>
            $inputq->enqueue(int(rand($task_time) + 1));
        <br>
        }
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        # make worker threads
        <br>
        my @children;
        <br>
        my $thr;
        <br>
        for (1 .. $num_children)
        <br>
        {
        <br>
            $children[$_] = $thr=threads->create(\&child, $_);
        <br>
            $thr->detach();
        <br>
        }
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        # watch for output from children
        <br>
        while (my $val = $outputq->dequeue())
        <br>
        {
        <br>
            # we got something...
        <br>
            print "parent received [$val]\tprocess check: ";
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
            # see if we're done and show state of children
        <br>
            # could probably simplify this to "last if
        (($inputq->pending() == 0) && ($outputq->pending()
        == 0));"
        <br>
            #   because if both queues are empty, then we're really
        finished, but this way
        <br>
            #   allows me to see the state of each child
        <br>
            my $running = 0;
        <br>
            for (my $c=1 ; $c <= $num_children ; $c++)
        <br>
            {
        <br>
                my $state = 'x';
        <br>
                if ($children[$c])
        <br>
                {
        <br>
                    if ($children[$c]->is_running())
        <br>
                    {
        <br>
                        $state = 'R';
        <br>
                        $running++;
        <br>
                    }
        <br>
                    else
        <br>
                    {
        <br>
                        $children[$c] = 0;
        <br>
                    }
        <br>
                }
        <br>
                print "$c=$state ";
        <br>
            }
        <br>
            print "\n";
        <br>
            last if (!$running);
        <br>
        }
        <br>
        print "parent done\n";
        <br>
        exit(0);
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        ####################
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
        # the work our children will do
        <br>
        sub child
        <br>
        {
        <br>
            my ($id) = @_;
        <br>
            my $arg;
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
            # while there is more work to do and we can pull something
        off
        <br>
            while ($inputq->pending() && ($arg =
        $inputq->dequeue()))
        <br>
            {
        <br>
                # do work
        <br>
                sleep($arg);
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
                # tell our parent the results
        <br>
                $outputq->enqueue("child $id had $arg");
        <br>
            }
        <br>
      </font>
      <font face="Helvetica, Arial, sans-serif"><br>
            # all the work is done, exit
        <br>
            print "child $id exiting\n";
        <br>
            return 1;
        <br>
        }
        <br>
        ===cut===
        <br>
        _______________________________________________
        <br>
        Dfw-pm mailing list
        <br>
        <a class="moz-txt-link-abbreviated" href="mailto:Dfw-pm@pm.org">Dfw-pm@pm.org</a>
        <br>
        <a class="moz-txt-link-freetext" href="http://mail.pm.org/mailman/listinfo/dfw-pm">http://mail.pm.org/mailman/listinfo/dfw-pm</a>
        <br>
      </font>
    </blockquote>
    <font face="Helvetica, Arial, sans-serif"><br>
    </font>
  </body>
</html>