test_semaphore_mt.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:7k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: test_semaphore_mt.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:10:32  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: test_semaphore_mt.cpp,v 1000.1 2004/06/01 19:10:32 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Andrei Gourianov, gouriano@ncbi.nlm.nih.gov
  35.  *
  36.  * File Description:
  37.  *   Test CSemaphore class in multithreaded environment
  38.  *   NOTE: in order to run correctly the number of threads MUST be even!
  39.  *
  40.  *   the test is a very simple producer/consumer model
  41.  *   one thread produces "items" (increments integer counter)
  42.  *  next thread consumes the same amount of items (decrements integer counter)
  43.  *  "Content" semaphore is used to notify consumers of how many items are
  44.  *   available.
  45.  *
  46.  */
  47. #include <ncbi_pch.hpp>
  48. #include <corelib/ncbithr.hpp>
  49. #include <corelib/ncbimtx.hpp>
  50. #include <corelib/ncbi_system.hpp>
  51. #include <corelib/test_mt.hpp>
  52. #include <test/test_assert.h>  /* This header must go last */
  53. USING_NCBI_SCOPE;
  54. /////////////////////////////////////////////////////////////////////////////
  55. //  Test application
  56. class CTestSemaphoreApp : public CThreadedApp
  57. {
  58. public:
  59.     virtual bool Thread_Init(int idx);
  60.     virtual bool Thread_Run(int idx);
  61. protected:
  62.     virtual bool TestApp_Init(void);
  63.     virtual bool TestApp_Exit(void);
  64. private:
  65.     // produce Num items
  66.     void Produce(int Num);
  67.     // consume Num items
  68.     void Consume(int Num);
  69.     static CSemaphore s_semContent, s_semStorage;
  70.     static int s_Counter, s_Id;
  71. };
  72. /////////////////////////////////////////////////////////////////////////////
  73. CSemaphore CTestSemaphoreApp::s_semContent(0,10);
  74. CSemaphore CTestSemaphoreApp::s_semStorage(1,1);
  75. int CTestSemaphoreApp::s_Counter=0;
  76. int CTestSemaphoreApp::s_Id=0;
  77. /////////////////////////////////////////////////////////////////////////////
  78. //  IMPLEMENTATION
  79. void CTestSemaphoreApp::Produce(int Num)
  80. {
  81.     // Storage semaphore acts as a kind of mutex - its only purpose
  82.     // is to protect Counter
  83.     s_semStorage.Wait();
  84.     s_Counter += Num;
  85.     NcbiCout << "+" << Num << "=" << s_Counter << NcbiEndl;
  86.     s_semStorage.Post();
  87.     // Content semaphore notifies consumer threads of how many items can be
  88.     // consumed. Slow consumption with fast production causes Content semaphore
  89.     // to overflow from time to time. We catch exception and wait for consumers
  90.     // to consume something
  91.     for (bool Posted=false; !Posted;) {
  92.         try {
  93.             s_semContent.Post(Num);
  94.             Posted = true;
  95.         }
  96.         catch (exception& e) {
  97.             NcbiCout << e.what() << NcbiEndl;
  98.             SleepMilliSec(500);
  99.         }
  100.     }
  101. }
  102. void CTestSemaphoreApp::Consume(int Num)
  103. {
  104.     for (int i = Num; i > 0; --i ) {
  105.         // we can only consume one by one
  106.         s_semContent.Wait();
  107.         s_semStorage.Wait();
  108.         --s_Counter;
  109.         NcbiCout << "-1=" << s_Counter << NcbiEndl;
  110.         s_semStorage.Post();
  111.         SleepMilliSec(500);
  112.     }
  113. }
  114. bool CTestSemaphoreApp::Thread_Init(int /*idx*/)
  115. {
  116.     return true;
  117. }
  118. bool CTestSemaphoreApp::Thread_Run(int idx)
  119. {
  120.     //  One thread produces, next - consumes;
  121.     //  production is fast, consumption is slow (because of Sleep).
  122.     //  NOTE:  In order to run correctly the number of threads MUST be even!
  123.     xncbi_SetValidateAction(eValidate_Throw);
  124.     if ( idx % 2 != 1) {
  125.         Consume((idx/2)%3 + 1);
  126.     } 
  127.     else {
  128.         Produce((idx/2)%3 + 1);
  129.     }
  130.     return true;
  131. }
  132. bool CTestSemaphoreApp::TestApp_Init(void)
  133. {
  134.     NcbiCout
  135.         << NcbiEndl
  136.         << "Testing semaphores with "
  137.         << NStr::IntToString(s_NumThreads)
  138.         << " threads"
  139.         << NcbiEndl;
  140.     if ( s_NumThreads%2 != 0 ) {
  141.         throw runtime_error("The number of threads MUST be even");
  142.     }
  143.     return true;
  144. }
  145. bool CTestSemaphoreApp::TestApp_Exit(void)
  146. {
  147.     NcbiCout
  148.         << "Test completed"
  149.         << NcbiEndl
  150.         << " counter = " << s_Counter
  151.         << NcbiEndl;
  152.     // storage must be available
  153.     assert( s_semStorage.TryWait() );
  154.     // content must be empty
  155.     assert( !s_semContent.TryWait() );
  156. assert( s_Counter == 0 );
  157.     return true;
  158. }
  159. /////////////////////////////////////////////////////////////////////////////
  160. //  MAIN
  161. int main(int argc, const char* argv[]) 
  162. {
  163.     // Execute main application function
  164.     return CTestSemaphoreApp().AppMain(argc, argv, 0, eDS_Default, 0);
  165. }
  166. /*
  167.  * ===========================================================================
  168.  * $Log: test_semaphore_mt.cpp,v $
  169.  * Revision 1000.1  2004/06/01 19:10:32  gouriano
  170.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.9
  171.  *
  172.  * Revision 6.9  2004/05/14 13:59:51  gorelenk
  173.  * Added include of ncbi_pch.hpp
  174.  *
  175.  * Revision 6.8  2003/05/14 16:26:23  ivanov
  176.  * Changed Sleep() to SleepMilliSec()
  177.  *
  178.  * Revision 6.7  2002/09/19 20:05:43  vasilche
  179.  * Safe initialization of static mutexes
  180.  *
  181.  * Revision 6.6  2002/04/23 13:11:50  gouriano
  182.  * test_mt.cpp/hpp moved into another location
  183.  *
  184.  * Revision 6.5  2002/04/16 18:49:09  ivanov
  185.  * Centralize threatment of assert() in tests.
  186.  * Added #include <test/test_assert.h>. CVS log moved to end of file.
  187.  *
  188.  * Revision 6.4  2002/03/19 20:29:48  gouriano
  189.  * added "windows.h"
  190.  *
  191.  * Revision 6.3  2002/03/14 19:10:04  gouriano
  192.  * added checking of number of threads
  193.  *
  194.  * Revision 6.2  2001/12/13 19:48:23  gouriano
  195.  * *** empty log message ***
  196.  *
  197.  * Revision 6.1  2001/12/10 18:37:29  gouriano
  198.  * *** empty log message ***
  199.  *
  200.  * ===========================================================================
  201.  */