summaryrefslogtreecommitdiff
path: root/docs/tutorials/013/page02.html
blob: 7fca9f39265c92b3f7c6cd3e3cfc81a18e839eca (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
113
114
115
116
117
118
119
120
121
122
<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>

<font color=red>// $Id$</font>

<font color=blue>#include</font> "<font color=green>mld.h</font>"
<font color=blue>#include</font> "<font color=green>task.h</font>"
<font color=blue>#include</font> "<font color=green>work.h</font>"
<font color=blue>#include</font> "<font color=green>block.h</font>"

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

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

        <font color=red>// Give the threads a chance to get ready.</font>
    <font color=#008888>ACE_OS::sleep</font> (ACE_Time_Value (1));

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

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

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

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

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

        <font color=red>// Delete our Task to prevent a memory leak</font>
    delete task;

        <font color=red>// Ask our memory leak detector if things are OK</font>
    if (MLD_COUNTER != 0)
    {
        ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Memory Leak! (counter = %d)\n</font>",MLD_COUNTER));
    }

    return (0);
}

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

    (void) run_test (iterations, threads, subtasks);

    ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Application exiting\n</font>"));

    exit (0);
}
<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>)
template class ACE_Guard &lt; ACE_Mutex >;
template class ACE_Lock_Adapter &lt; ACE_Mutex >;
template class ACE_Atomic_Op &lt; ACE_Mutex, int >;
<font color=blue>#elif defined</font> (<font color=purple>ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA</font>)
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Guard&lt;ACE_Mutex>;
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Lock_Adapter&lt;ACE_Mutex>;
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Atomic_Op&lt;ACE_Mutex, int>;
<font color=blue>#endif</font> <font color=red>/*
         ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION 
       */</font>
</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>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER>