測試的思路
我先後啟動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;
}
本文配套源碼