利用临界区的多线程同步测试
作者:fs007
下载源代码
我先后启动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;
}