summaryrefslogtreecommitdiff
path: root/docs/tutorials/013/page02.html
blob: 785b0c86b75bf392b2b0b81d4605677cc8e1a4e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="Author" CONTENT="James CE Johnson">
   <TITLE>ACE Tutorial 013</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">

<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER>

<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER>


<P>
<HR WIDTH="100%">
<P>
We'll go back to our tradition of looking at main() first.  The only
change here from our "normal" thread pool is the ability to specify
the number of subtasks for the pool.  (Each subtask is another thread
pool in the chain.  I suppose I should have named that better...)
I've still got the custom Message_Block so that, at this level, we
don't even know about custom Data_Blocks.
<P>
<HR WIDTH="100%">
<PRE>
#include "mld.h"
#include "task.h"
#include "work.h"
#include "block.h"

int run_test (int iterations, int threads, int subtasks)
{
        // Create a task with some subtasks.  Each Task is a thread
        // pool of 'threads' size.  If a task has a subtask, it will
        // forward the unit of work to the subtask when finished.  See 
        // task.{h|cpp} for more details.
    Task * task = new Task(subtasks);

    if (task->open (threads) == -1)
    {
        ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1);
    }

        // Give the threads a chance to get ready.
    ACE_OS::sleep (ACE_Time_Value (1));

    for (int i = 0; i < iterations; ++i)
    {
            // Create a custom message block that can contain our Work object
        Message_Block *message = new Message_Block( new Work(i) );

            // Put the "unit of work" into the message queue
        if (task->putq (message) == -1)
        {
        	ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putq"), -1);
        }
    }

        // The default constructor of our custom message block will
        // insert a message telling our task to shutdown.
    Message_Block *message = new Message_Block( );

        // Put the shutdown request into the thread pool
    if (task->putq (message) == -1)
    {
      	ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putq"), -1);
	}

        // Wait for the task to shut down.  Any subtasks will also be
        // waited for.
    task->wait ();

        // Delete our Task to prevent a memory leak
    delete task;

        // Ask our memory leak detector if things are OK
    if( MLD_COUNTER->value() != 0 )
    {
      	ACE_DEBUG ((LM_DEBUG, "(%P|%t) Memory Leak!\n"));
    }
        
    return (0);
}

int main (int argc, char *argv[])
{
        // Number of Work objects to put into the Task pool
    int iterations = argc > 1 ? atoi (argv[1]) : 4;
        // Number of threads for each Task
    int threads = argc > 2 ? atoi (argv[2]) : 2;
        // Number of tasks to chain after the primary task
    int subtasks = argc > 3 ? atoi(argv[3]) : 1;
    
    (void) run_test (iterations, threads, subtasks);

    ACE_DEBUG ((LM_DEBUG, "(%P|%t) Application exiting\n"));

    exit (0);
}
</PRE>
<HR WIDTH="100%">
<P>
Nothing really surprising here...  Just remember that your total
number of threads is ( ( 1 + subtasks ) * threads ).  You probably
don't want to get too carried away with that!
<P>
<HR WIDTH="100%">
<CENTER>[<A HREF="..">Tutorial Index</A>] [<A HREF="page03.html">Continue
This Tutorial</A>]</CENTER>

</BODY>
</HTML>