分类: C/C++
2008-04-23 21:42:02
利用临界区的多线程同步测试
作者:
测试的思路
我先后启动10个线程,每个线程都往一个文本文件(1.txt)中写自己的信息,每个线程写100次。每次信息包括它的线程id,以及时间,并用两条横线将一条信息包括起来。
测试步骤
选择同步和不选择同步,各测试一次。
测试结果
当不选择同步时,我们可以发现在记录的文本中每条信息的两条横线没有一一对应,排列混乱。
选择同步时,我们可以发现在记录的文本中每条信息的两条横线一一对应,并且按顺序排列。程序耗时较多。
结论
当利用临界区同步时,同一时刻每次只有一个线程可以往文件中写入信息,这样可以保证每条信息的完整。
由于当一个线程写入的时候,其他线程必须等待,所以同步时耗时也较多。
主要代码如下
//建一个供测试使用的文件类
class CMyfile { public: CMyfile() { InitializeCriticalSection(&cs); } ~CMyfile() { DeleteCriticalSection(&cs); } void msglog(char* buffer,int length,int wait) { static int i=0; CString a; a.Format("%d#",i ); if (m_bSync) EnterCriticalSection(&cs); fwrite("\n", 1, 1, fstream); fwrite(a CString(''-'',50), 52, 1, fstream); fwrite("\n", 1, 1, fstream); fwrite(buffer, length, 1, fstream); Sleep(wait); fwrite("\n", 1, 1, fstream); fwrite(a CString(''-'',50), 52, 1, fstream); fflush(fstream); if (m_bSync) LeaveCriticalSection(&cs); } bool openfile(CString filename,bool bSync) { m_filename=filename; m_bSync=bSync; if((fstream=fopen(filename, "wt")) == NULL) return false ; else return true; } void closefile() { fclose(fstream); } protected: CRITICAL_SECTION cs; FILE* fstream; CString m_filename; bool m_bSync; private: };
测试代码:
UINT threadFunc( LPVOID p); void CBDlg::OnButton2() { // TODO: Add your control notification handler code here CMyfile file; if (m_sync.GetCheck()==1) file.openfile("1.txt",true);//同步 else file.openfile("1.txt",false);//异步 CWinThread* thd[10]; HANDLE hThd[10]; for(int i=0;i<10;i ) { thd[i]=AfxBeginThread(threadFunc,&file); //故意制造线程启动时间的不一致 Sleep(10); hThd[i]=thd[i]->m_hThread; } //等待所有线程结束 WaitForMultipleObjects(10,hThd,true,INFINITE); file.closefile(); AfxMessageBox("ok"); } UINT threadFunc( LPVOID p) { CMyfile* file=(CMyfile*)p; long lThreadID = ::AfxGetThread()->m_nThreadID; CString a; a.Format("thread %d",lThreadID); for (int i=0;i<100;i ) { CTime time=CTime::GetCurrentTime(); CString str=time.Format("%y-%m-%d %H:%M:%S"); str=str "--------->" a; file->msglog(str.GetBuffer(str.GetLength()),str.GetLength(),lThreadID/100); } return 1; }