⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cxx

📁 pwlib源码库
💻 CXX
字号:
/* * main.cxx * * PWLib application source file for ThreadSafe * * Main program entry point. * * Copyright 2002 Equivalence * * $Log: main.cxx,v $ * Revision 1.8  2004/10/14 12:31:46  rjongbloed * Added synchronous mode for safe collection RemoveAll() to wait until all objects *   have actually been deleted before returning. * * Revision 1.7  2004/09/07 11:32:02  rjongbloed * Changed function name in PSafeCollection to something more standard for collections * * Revision 1.6  2004/04/04 13:24:19  rjongbloed * Changes to support native C++ Run Time Type Information * * Revision 1.5  2003/10/27 22:12:56  dereksmithies * Add more good changes to get Compare method work. Thanks to Gene Small * * Revision 1.4  2003/10/13 23:38:31  dereksmithies * Add debugging statements, usage(), Fixed Compare method. Thanks Gene Small. * * Revision 1.3  2002/12/11 03:38:45  robertj * Added more tests * * Revision 1.2  2002/05/02 00:30:26  robertj * Added dump of thread times during start up. * * Revision 1.1  2002/05/01 04:16:44  robertj * Added thread safe collection classes. * */#include <ptlib.h>#include "main.h"#include <ptclib/random.h>PCREATE_PROCESS(ThreadSafe);///////////////////////////////////////////////////////////////////////////////TestObject::TestObject(ThreadSafe & proc, unsigned val)  : process(proc){  value = val;  process.mutexObjects.Wait();  process.totalObjects++;  process.currentObjects++;  process.mutexObjects.Signal();}TestObject::~TestObject(){  process.mutexObjects.Wait();  process.currentObjects--;  process.mutexObjects.Signal();}PObject::Comparison TestObject::Compare(const PObject & obj) const{  PAssert(PIsDescendant(&obj, TestObject), PInvalidCast);  unsigned othervalue = ((const TestObject &)obj).value;        if (value < othervalue)    return LessThan;  if (value > othervalue)    return GreaterThan;   return EqualTo;}void TestObject::PrintOn(ostream & strm) const{  strm << value;}///////////////////////////////////////////////////////////////////////////////ThreadSafe::ThreadSafe()  : PProcess("Equivalence", "ThreadSafe", 1, 0, AlphaCode, 1){  threadCount = 0;  totalObjects = 0;  currentObjects = 0;}ThreadSafe::~ThreadSafe(){  unsorted.RemoveAll(TRUE);  sorted.RemoveAll(TRUE);  sparse.RemoveAll(TRUE);}void ThreadSafe::Usage(){  cout << "Usage: threadsafe {options} [number]" << endl       << "-t (more t's for more detail) logging on" << endl       << "-o output file for logging" << endl       << "-1 (or --test1) carry out test 1" << endl       << "-2 (or --test2) carry out test 2" << endl       << "-3 (or --test3) carry out test 3" << endl        << "The number field is optional, and specifies the number of threads for test 1" << endl       << endl;  return;}void ThreadSafe::Main(){  PArgList & args = GetArguments();  args.Parse(             "t-trace."       "-no-trace."	     "o-output:"      "-no-output."	     "1-test1."       "-no-test1."             "2-test2."       "-no-test2."             "3-test3."       "-no-test3.");  PTrace::Initialise(args.GetOptionCount('t'),                     args.HasOption('o') ? (const char *)args.GetOptionString('o') : NULL,                     PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine);  if (args.HasOption('1'))    Test1(args);  else if (args.HasOption('2'))    Test2(args);  else if (args.HasOption('3'))    Test3(args);  else    Usage();}void ThreadSafe::Test1(PArgList & args){  if (args.GetCount() > 0)    threadCount = args[0].AsUnsigned();  else    threadCount = 99;  cout << "Starting " << threadCount << " threads." << endl;  for (PINDEX i = 0; i < threadCount; i++) {    PTimeInterval duration = PRandom::Number()%540000 + 60000;    cout << setw(4) << (i + 1) << '=' << duration;    if (i%5 == 4)      cout << '\n';    PThread::Create(PCREATE_NOTIFIER(Test1Thread), (INT)duration.GetMilliSeconds());  }  cout << endl;  startTick = PTimer::Tick();  while (threadCount > 0) {    Test1Output();    Sleep(5000);  }  Test1OutputEnd();  sorted.RemoveAll();  unsorted.RemoveAll();  sparse.RemoveAll();  Test1OutputEnd();}void ThreadSafe::Test1Output(){  PSafePtr<TestObject> ptr;  sorted.DeleteObjectsToBeRemoved();  unsorted.DeleteObjectsToBeRemoved();  sparse.DeleteObjectsToBeRemoved();  cout << setprecision(0) << setw(5) << (PTimer::Tick() - startTick)       << " Threads=" << threadCount       << ", Unsorted=" << unsorted.GetSize()       << ", Sorted=" << sorted.GetSize()       << ", Dictionary=" << sparse.GetSize()       << ", Objects:";  mutexObjects.Wait();  cout << currentObjects << '/' << totalObjects << endl;  mutexObjects.Signal();  }void ThreadSafe::Test1OutputEnd(){  PSafePtr<TestObject> ptr;  Test1Output();  cout << setprecision(0) << setw(5) << (PTimer::Tick() - startTick) << " Unsorted:" << endl;  for (ptr = unsorted.GetAt(0, PSafeReference); ptr != NULL; ++ptr) {    cout << *ptr << endl;  }      cout << setprecision(0) << setw(5) << (PTimer::Tick() - startTick) << " Sorted:" << endl;  for (ptr = sorted.GetAt(0, PSafeReference); ptr != NULL; ++ptr) {    cout << *ptr << endl;  }  cout << setprecision(0) << setw(5) << (PTimer::Tick() - startTick) << " Sparse:" << endl;  for (ptr = sparse.GetAt(0, PSafeReference); ptr != NULL; ++ptr) {    cout << *ptr << endl;  }}void ThreadSafe::Test1Thread(PThread &, INT duration){  PRandom random;  PSafePtr<TestObject> ptr;  PTimer timeout = duration;  while (timeout.IsRunning()) {    switch (random%17) {      case 0 :        if (random%(unsorted.GetSize()+1) == 0) 	          unsorted.Append(new TestObject(*this, random));        break;      case 1 :        if (random%(sorted.GetSize()+1) == 0)           sorted.Append(new TestObject(*this, random));        break;      case 2 :        sparse.SetAt(random%20, new TestObject(*this, random));        break;      case 3 :        for (ptr = unsorted.GetAt(0, PSafeReference); ptr != NULL; ++ptr) {          if (random%50 == 0)            unsorted.Remove(ptr);        }        break;      case 4 :        for (ptr = sorted.GetAt(0, PSafeReference); ptr != NULL; ++ptr) {          if (random%50 == 0)            sorted.Remove(ptr);        }        break;      case 5 :        sparse.RemoveAt(random%20);        break;      case 6 :        for (ptr = unsorted; ptr != NULL; ++ptr)          Sleep(random%50);        break;      case 7 :        for (ptr = sorted; ptr != NULL; ++ptr)          Sleep(random%50);        break;      case 8 :        for (ptr = sparse; ptr != NULL; ++ptr)          Sleep(random%50);        break;      case 9 :        for (ptr = unsorted.GetAt(0, PSafeReadOnly); ptr != NULL; ++ptr)          Sleep(random%50);        break;      case 10 :        for (ptr = sorted.GetAt(0, PSafeReadOnly); ptr != NULL; ++ptr)          Sleep(random%50);        break;      case 11 :        for (ptr = sparse.GetAt(0, PSafeReadOnly); ptr != NULL; ++ptr)          Sleep(random%50);        break;      case 12 :        for (ptr = unsorted.GetAt(0, PSafeReference); ptr != NULL; ++ptr)          Sleep(random%50);        break;      case 13 :        for (ptr = sorted.GetAt(0, PSafeReference); ptr != NULL; ++ptr)          Sleep(random%50);        break;      case 14 :        for (ptr = sparse.GetAt(0, PSafeReference); ptr != NULL; ++ptr)          Sleep(random%50);        break;      case 15 :        if ( unsorted.GetSize() > 0 ) {	  PSafePtr<TestObject> ptr2 = unsorted.GetAt(unsorted.GetSize() - 1, PSafeReadOnly);	  if ( ptr2 != NULL )            ptr2 = unsorted.FindWithLock(*ptr2, PSafeReadOnly);	}		        break;      case 16 :        if ( sorted.GetSize() > 0 ) {	  PSafePtr<TestObject> ptr2 = unsorted.GetAt(sorted.GetSize() - 1, PSafeReference);	  if ( ptr2 != NULL )            ptr2 = sorted.FindWithLock(*ptr2, PSafeReference);	}        break;    }    Sleep(random%500);  }  threadCount--;}void ThreadSafe::Test2(PArgList &){  sparse.SetAt(0, new TestObject(*this, 0));  threadCount = 2;  PThread::Create(PCREATE_NOTIFIER(Test2Thread1));  PThread::Create(PCREATE_NOTIFIER(Test2Thread2));  while (threadCount > 0)    Sleep(1000);}void ThreadSafe::Test2Thread1(PThread &, INT){  cout << "Thread 1 before read only lock" << endl;  PSafePtr<TestObject> ptr = sparse.FindWithLock(0, PSafeReadOnly);  cout << "Thread 1 after read only lock, pausing ..." << endl;  Sleep(3000);  cout << "Thread 1 before read write lock" << endl;  ptr = sparse.FindWithLock(0, PSafeReadWrite);  cout << "Thread 1 after read write lock, exiting" << endl;  threadCount--;}void ThreadSafe::Test2Thread2(PThread &, INT){  Sleep(1000);  cout << "Thread 2 before read write lock" << endl;  PSafePtr<TestObject> ptr = sparse.FindWithLock(0, PSafeReadWrite);  cout << "Thread 2 after read write lock, exiting" << endl;  threadCount--;}void ThreadSafe::Test3(PArgList &){  for (PINDEX i = 0; i < 10; i++)    unsorted.Append(new TestObject(*this, i));  threadCount = 2;  PThread::Create(PCREATE_NOTIFIER(Test3Thread1));  PThread::Create(PCREATE_NOTIFIER(Test3Thread2));  while (threadCount > 0)    Sleep(1000);}void ThreadSafe::Test3Thread1(PThread &, INT){  {    cout << "Thread 1 before read only lock" << endl;    PSafePtr<TestObject> ptr = unsorted.GetAt(2, PSafeReadOnly);    cout << "Thread 1 after read only lock, pausing ..." << endl;    Sleep(2000);    cout << "Thread 1 before read write lock" << endl;    ptr.SetSafetyMode(PSafeReadWrite);    cout << "Thread 1 after read write lock, before ptr going out of scope" << endl;  }  cout << "Thread 1 after ptr out of scope, exiting" << endl;  threadCount--;}void ThreadSafe::Test3Thread2(PThread &, INT){  Sleep(1000);  cout << "Thread 2 before enumeration" << endl;  PSafePtr<TestObject> ptr = unsorted.GetAt(0, PSafeReadOnly);  while (ptr != NULL) {    if (ptr->value == 2) {      cout << "Thread 2 before read write lock" << endl;      ptr->LockReadWrite();      cout << "Thread 2 after read write lock" << endl;      Sleep(2000);      cout << "Thread 2 before read write unlock" << endl;      ptr->UnlockReadWrite();      cout << "Thread 2 after read write unlock" << endl;    }    ptr++;  }  cout << "Thread 2 after enumeration, exiting" << endl;  threadCount--;}// End of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -