///////////////////////////////////////////////////////////////////// // shareConflict.cpp - demonstrate sharing problems // // // // Two threads attempt to modify a shared string without // // serializing access. // // // // Jim Fawcett, CSE691 - Software Modeling & Analysis, Fall 2000 // ///////////////////////////////////////////////////////////////////// #include #include #include #include #include using namespace std; // // This program creates two threads which each process the same // string. The shared string gets corrupted because access is // not serialized. That is, we don't force the threads to take // turns acting on the string. This will be fixed in share2.cpp // //----< thread processing function >--------------------------- unsigned int __stdcall threadProc1(void *pData) { //Sleep(0); // put here simply to keep thread 1 from finishing // before thread 2 starts its loop. string *pStr = (string*)pData; if(pStr->size() == 0) (*pStr) = "\nThis is a string created by thread1"; int i; for(i=0; i<55; i++) { if(pStr->size() < 70) pStr->append(", added by thread1"); else { cout << (*pStr).c_str(); *pStr = "\nstring created by thread1"; } } return 0; } //----< thread processing function >--------------------------- unsigned int __stdcall threadProc2(void *pData) { string *pStr = (string*)pData; if(pStr->size() == 0) (*pStr) = "\nThis is a string created by thread2"; int i; for(i=0; i<55; i++) { if(pStr->size() < 70) pStr->append(", added by thread2"); else { cout << (*pStr).c_str(); *pStr = "\nstring created by thread2"; } } return 0; } // //----< entry point for process >------------------------------ void main() { cout << "\n Demonstrate the Operation of Mult-threaded Code " << "\n without using synchronized access to shared resources" << "\n=======================================================\n\n"; // define an array of handles to threads, needed to wait // for their completion const int NumHandles = 2; HANDLE thHand[NumHandles]; // define argument values for thread #1 _beginthreadex string shared; void* Security = NULL; // no security attributes unsigned int StackSize = 0; // stack size picked by OS unsigned int(__stdcall threadProc1)(void*); // name of thread function unsigned int InitFlag = 0; // start running unsigned int ThreadID[2]; // receives thread id void *Arg = &shared; // pointer to argument // start first thread thHand[0] = (HANDLE)_beginthreadex( Security, StackSize, threadProc1, Arg, InitFlag, &ThreadID[0] ); // start second thread thHand[1] = (HANDLE)_beginthreadex( Security, StackSize, threadProc2, Arg, InitFlag, &ThreadID[1] ); // tell process to wait for both threads to complete // before terminating BOOL fwait = TRUE; // wait for all handles DWORD timeOut = INFINITE; // time out in milliseconds WaitForMultipleObjects(NumHandles, thHand, fwait, timeOut); CloseHandle(thHand[0]); // return resources CloseHandle(thHand[1]); // return resources cout << "\n\n"; }