📄 combine.shar
字号:
$echo 'restore of' 'page04.pre' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'page04.pre:' 'MD5 check failed'
fec9a7b5b9b2a8f61c0178aaf1b78a91 page04.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`"
test 138 -eq "$shar_count" ||
$echo 'page04.pre:' 'original size' '138,' 'current size' "$shar_count!"
fi
fi
# ============= page05.pre ==============
if test -f 'page05.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page05.pre' '(file already exists)'
else
$echo 'x -' extracting 'page05.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' &&
X
Our <A HREF="task.cpp">Task</A> object definition.
<P>
Something to look at here is the ACE_Barrier usage. In the
constructor, we tell the barrier how many threads we're using. Then,
in the svc() method, we use the barrier's wait() method. You can
think of the barrier as a semaphore initialized to the thread count.
X Each time wait()
is invoked, the semaphore is decremented and the thread is blocked.
X When the count equals zero, all threads are unblocked and allowed to
continue.
<P>
<font size=-1>Note: This isn't the way ACE_Barrier really works, it's
just an analogy</font>
X
<HR WIDTH="100%">
SHAR_EOF
$shar_touch -am 03191459100 'page05.pre' &&
chmod 0664 'page05.pre' ||
$echo 'restore of' 'page05.pre' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'page05.pre:' 'MD5 check failed'
ff8fe38f39f3860bcd45aa450cb754da page05.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`"
test 606 -eq "$shar_count" ||
$echo 'page05.pre:' 'original size' '606,' 'current size' "$shar_count!"
fi
fi
# ============= page06.pre ==============
if test -f 'page06.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page06.pre' '(file already exists)'
else
$echo 'x -' extracting 'page06.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page06.pre' &&
X
Since I added Block just to give us output, let's take a look at that output.
X
<P>
<HR WIDTH="100%">
<PRE>
[jcej@chiroptera 010]$./message_queue 4 2
(8910|1024) Task ctor 0xbffff9c4
(8910|2050) Task 0xbffff9c4 starts in thread 2050
(8910|1025) Task 0xbffff9c4 starts in thread 1025
(8910|1024) Block ctor 0x8052398
(8910|1024) Block ctor 0x8052488
(8910|1024) Block ctor 0x8052578
(8910|1024) Block ctor 0x8052668
(8910|1024) Block ctor 0x8052758
(8910|1025) Block 0x8052398 contains (This is message 0.)
(8910|2050) Block 0x8052488 contains (This is message 1.)
(8910|1025) Block dtor 0x8052398
(8910|1025) Block 0x8052578 contains (This is message 2.)
(8910|2050) Block dtor 0x8052488
(8910|2050) Block 0x8052668 contains (This is message 3.)
(8910|1025) Block dtor 0x8052578
(8910|1025) Task close 0xbffff9c4
(8910|2050) Block dtor 0x8052668
(8910|2050) Task close 0xbffff9c4
(8910|1024) Task dtor 0xbffff9c4
(8910|1024) Block dtor 0x8052758
(8910|1024) Application exiting
[jcej@chiroptera 010]$
</PRE>
<HR WIDTH="100%">
<P>
Notice that each <i>Block ctor</i> has a corresponding <i>Block dtor</i>.
We've proven the point that all memory gets cleaned up. We also see that
both threads get to do some work and that both close as expected.
<P>
It's also worth mentioning that it's just an accident that all of the blocks
are created and enqueued before any are processed. Run the test on a multi-processor
or with more iterations and you'll see some get processed before all are created.
SHAR_EOF
$shar_touch -am 03191459100 'page06.pre' &&
chmod 0664 'page06.pre' ||
$echo 'restore of' 'page06.pre' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'page06.pre:' 'MD5 check failed'
d2a471df09308f89a611a7aa0218737f page06.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`"
test 1493 -eq "$shar_count" ||
$echo 'page06.pre:' 'original size' '1493,' 'current size' "$shar_count!"
fi
fi
# ============= page07.pre ==============
if test -f 'page07.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page07.pre' '(file already exists)'
else
$echo 'x -' extracting 'page07.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page07.pre' &&
X
That's it for Tutorial 10. There are some esoteric changes between the thread-pool server
and this application but it's basically the same. In the next tutorial I'll modify this just
a bit to move non-trivial data through the queue.
<P>
X
<UL>
<LI><A HREF="Makefile">Makefile</A>
<LI><A HREF="block.h">block.h</A>
<LI><A HREF="message_queue.cpp">message_queue.cpp</A>
<LI><A HREF="task.cpp">task.cpp</A>
<LI><A HREF="task.h">task.h</A>
</UL>
SHAR_EOF
$shar_touch -am 03191459100 'page07.pre' &&
chmod 0664 'page07.pre' ||
$echo 'restore of' 'page07.pre' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'page07.pre:' 'MD5 check failed'
07ae8f9b2a400e46ab102ab8c40a8b81 page07.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page07.pre'`"
test 444 -eq "$shar_count" ||
$echo 'page07.pre:' 'original size' '444,' 'current size' "$shar_count!"
fi
fi
# ============= page02.pst ==============
if test -f 'page02.pst' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page02.pst' '(file already exists)'
else
$echo 'x -' extracting 'page02.pst' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page02.pst' &&
<HR WIDTH="100%">
<P>
This looks a lot like our thread-pool server and it even does some things
better. In particular, I've scoped the Task object so that it's destructor
will have a chance to get called before the application exits.
Notice how we write actual data into the message block though. In the thread-pool
server we just provided a pointer. Writting the data is actually a more correct
way of doing things since you don't get into strange pointer casting situations.
What if you want to put complex objects into the message block though? We'll do
that in the next tutorial, let's stick with the basics first.
<P>
On the next page we'll take a look at our Block object...
<P>
SHAR_EOF
$shar_touch -am 03191459100 'page02.pst' &&
chmod 0664 'page02.pst' ||
$echo 'restore of' 'page02.pst' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'page02.pst:' 'MD5 check failed'
10957f28adbff16015bd94bdc01cd779 page02.pst
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pst'`"
test 689 -eq "$shar_count" ||
$echo 'page02.pst:' 'original size' '689,' 'current size' "$shar_count!"
fi
fi
# ============= page03.pst ==============
if test -f 'page03.pst' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page03.pst' '(file already exists)'
else
$echo 'x -' extracting 'page03.pst' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page03.pst' &&
<HR WIDTH="100%">
<P>
Ok, nothing really magic there. Some folks just feel a little uncomfortable
not doing an explicit <i>delete</i> on objects they've <i>new</i>'d so I
wanted to show you that the memory really does get cleaned up.
X
SHAR_EOF
$shar_touch -am 03191459100 'page03.pst' &&
chmod 0664 'page03.pst' ||
$echo 'restore of' 'page03.pst' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'page03.pst:' 'MD5 check failed'
fe792e145798cee96c099bf4026cf8ef page03.pst
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pst'`"
test 236 -eq "$shar_count" ||
$echo 'page03.pst:' 'original size' '236,' 'current size' "$shar_count!"
fi
fi
# ============= page04.pst ==============
if test -f 'page04.pst' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page04.pst' '(file already exists)'
else
$echo 'x -' extracting 'page04.pst' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page04.pst' &&
<HR WIDTH="100%">
<P>
The only thing here that we didn't see in the thread-pool server is the
ACE_Barrier. The application logic really doesn't need it but it is a
handy way to synchronize the threads at the beginning of svc(). In testing
I found that if I didn't sync svc(), the first thread to get activated would
tend to get all of the messages before the other threads came alive.
SHAR_EOF
$shar_touch -am 03191459100 'page04.pst' &&
chmod 0664 'page04.pst' ||
$echo 'restore of' 'page04.pst' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'page04.pst:' 'MD5 check failed'
2212efef5c096791808b00a5212c4376 page04.pst
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pst'`"
test 387 -eq "$shar_count" ||
$echo 'page04.pst:' 'original size' '387,' 'current size' "$shar_count!"
fi
fi
# ============= page05.pst ==============
if test -f 'page05.pst' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page05.pst' '(file already exists)'
else
$echo 'x -' extracting 'page05.pst' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page05.pst' &&
<HR WIDTH="100%">
<P>
This is all pretty straight-forward too. One gottcha we avoided was a memory leak
due to our shutdown message. Notice that svc() enqueues that block without bothering
to see if there are any more threads to dequeue it. Thats why our dtor can call getq()
without worrying about blocking infinitely: it knows the message block will be there.
<P>
Also notice that we haven't used <i>THR_DETACHED</i> in this
X tutorial. Why? Because in <i>message_queue.cpp</i> we call
X <i>wait()</i> to wait for all of the task's threads to exit.
X That prevents the leak that we normally avoid by using <i>THR_DETACHED</i>.
SHAR_EOF
$shar_touch -am 03191459100 'page05.pst' &&
chmod 0664 'page05.pst' ||
$echo 'restore of' 'page05.pst' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'page05.pst:' 'MD5 check failed'
802d999314ebcf28ebbffe6fb6dedcfa page05.pst
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pst'`"
test 647 -eq "$shar_count" ||
$echo 'page05.pst:' 'original size' '647,' 'current size' "$shar_count!"
fi
fi
rm -fr _sh32552
exit 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -