///////////////////////////////////////////////////////////////////////// // shared.cpp - demonstration of thread and lockingPtr Classes // // ver 2.0 // // Language: Visual C++, ver 6.0, SP 5 // // Platform: Dell Dimension 8100, Win 2000 Pro, SP 2 // // Application: CSE691/791 - SWM&A Demonstration // // Author: Jim Fawcett, CST 2-187, Syracuse Univ // // (315) 443-3948, jfawcett@twcny.rr.com // // // ///////////////////////////////////////////////////////////////////////// /* Module Operations ================= This module demonstrates the operation of thread and lockingPtr classes. The thread class is a relatively simple incapsulation of Win32 API threading. It uses an object of a class derived from the abstract processing class to define the processing required of the thread. The processing base class is defined in the threads module. The lockingPtr class provides mutually exclusive access to an object shared between two or more threads. Its constructor locks the object using a critical section and its destructor unlocks the object. The best use of a lockingPtr object is to create a temporary and use it to lock the object for a single operation. This is illustrated in the thrd1Proc::run() and thrd2Proc::run() functions. The main() function in this module creates a string and passes it to each of two thread processing functions in their constructions. They each create a reference member to it, and so, will share this common string. When started the threads run their respective proc functions that write the identifier "thread1 " or "thread2 " to it so we can see them interacting through this shared object. */ ///////////////////////////////////////////////////////////////////////// // Build Process // ///////////////////////////////////////////////////////////////////////// // Required Files: // // shared.cpp, threads.h, threads.cpp, lockingPtr.h, lockingPtr.cpp // // // // Compiler Command: // // cl /GX /MTd threadSync.cpp threads.cpp lockingPtr.cpp // // // ///////////////////////////////////////////////////////////////////////// /* Maintenance History: ==================== ver 1.0 : 27 Feb 02 - first release */ // #include #include "threads.h" #include "lockingPtr.h" using namespace std; /////////////////////////////////////////////////////////////// // This GlobalMutex object uses a static critical section // to provide mutually exclusive access to shared resources. // Because the underlying critical section is static, it is // shared by every GlobalMutex<1> object declared anywhere // in this process. typedef GlobalMutex<1> GMtx; /////////////////////////////////////////////////////////////// // processing for first thread class thrd1Proc : public processing { public: thrd1Proc(string &s) : _str(s) { _str = "\n "; } void run() { safeOut out(cout); GMtx mtx; for(int i=0; i<20; i++) { if(_str.size() > 70) lockingPtr(_str,mtx)->operator=("\n "); else lockingPtr(_str,mtx)->operator+=("thread1 "); mtx.lock(); cout << _str; mtx.unlock(); ::Sleep(0); // relinquish control } } private: string &_str; }; // /////////////////////////////////////////////////////////////// // processing for second thread class thrd2Proc : public processing { public: thrd2Proc(string &s) : _str(s) { _str = "\n "; } void run() { safeOut out(cout); GMtx mtx; for(int i=0; i<20; i++) { if(_str.size() > 70) lockingPtr(_str,mtx)->operator=("\n "); else lockingPtr(_str,mtx)->operator+=("thread2 "); mtx.lock(); cout << _str; mtx.unlock(); ::Sleep(0); // relinquish control } } private: string &_str; }; //---< entry point >----------------------------------------------------- void main() { cout << "\n Demonstrate two threads reading & writing same string " << "\n =======================================================\n"; string shared; /////////////////////////////////////////////////// // define processing for 1st thread and create it thrd1Proc proc1(shared); thread t1(proc1); /////////////////////////////////////////////////// // define processing for 2nd thread and create it thrd2Proc proc2(shared); thread t2(proc2); t1.start(); t2.start(); /////////////////////////////////////////////////// // make main thread wait for t1 and t1 to finish t1.wait(); t2.wait(); }