求救线程安全问题!希望高人多多指教!
tonsz 2006-06-20 08:49:42
很烦的问题,有那位高人可以指点一下:
线程操作串口,每0.5ms发送一次读数据请求,并接收一次数据
操作系统为WinXP,CPU空闲时,收发都正常,
但是一开大程序,CPU忙时,就收数不正确。
线程的优先级不能提得太高,因为定时的查询会使系统不响应
而较低的优先级和空闲模式都会出错。
线程操作的都是全局变量。
不知是因为什么原因造成的,
线程的安全很不好做呀!
有什么好的建议没有呀?
急需各位高人指点。
小的谢了先!
部分源代码:
/*---------------------------------------------------------------------------
Function Name:TFormMain::FormCreate
Usefullness:创建线程
About in Parameter:
About out Parameter:
The date:2004-10-30 11:17:09
---------------------------------------------------------------------------*/
void __fastcall TFormMain::StartSampleClick(TObject *Sender)
{
nCurrentHndShk = 0;
bFlagTerminateThread = true;
QueryPerformanceFrequency(&rFreq);
rInterval.QuadPart = dPickGap * rFreq.QuadPart / 1000;
QueryPerformanceCounter(&rStart);
DWORD ThreadID;
HANDLE hthread = CreateThread(0, 0, TimerThreadProc, 0, 0, &ThreadID);
if (hthread == 0)
{
ShowMessage("线程创建失败!");
if (hComm == 0) return;
// 实际关闭通信端口
CloseHandle(hComm );
return;
}
SetThreadPriority(hthread, THREAD_PRIORITY_IDLE);
}
/*---------------------------------------------------------------------------
Function Name:TimerThreadProc
Usefullness:定时的发送握手命令
About in Parameter:
About out Parameter:
The date: 2006-3-13 9:09:09
---------------------------------------------------------------------------*/
DWORD CALLBACK TimerThreadProc(void * p)
{
DWORD nBytesRead,dwCommError,i,ReadLen;
COMSTAT CS;
do {
rEnd.QuadPart = rStart.QuadPart + rInterval.QuadPart;
do {
QueryPerformanceCounter(&rStart);
} while (rStart.QuadPart < rEnd.QuadPart);
rStart = rEnd;
switch (nCuntHndCyc)
{
//头一次发握手信号,不用接收
case 0:
PurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 资料
WriteFile(hComm,&byHnd[nCurrentHndShk],1, &lrc, NULL);
nCuntHndCyc = 1;
break;
//nCuntHndCyc为一,即已经等待了一个周期,
//开始接收数据,并完成数据转化
//清空串口数据,开始下一次发送握手信号
//nCuntHndCyc为二时,表示为接收完全部数据又等待了一个周期
//如果还是没有收到,进行三的状态,进行重新发送
case 1:
case 2:
//使用ClearCommError得知有多少的数据在缓冲区中
ClearCommError(hComm,&dwCommError,&CS); //取得状态
if (CS.cbInQue >= 4) //!= 0) //若缓冲区有足够数据,则读取
{
ReadLen = CS.cbInQue;
if (ReadLen > sizeof(szInputBuffer))
{
PurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 资料
WriteFile(hComm,&byHnd[nCurrentHndShk],1, &lrc, NULL);
}
else
{
//读取数据
if (ReadFile(hComm, szInputBuffer,ReadLen,&nBytesRead,NULL)) // 接收COM 的数据
{
// PurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 资料
nCurrentHndShk = (nCurrentHndShk < nTotleHndShk) ? (nCurrentHndShk+1):0;
// for (int i=0; i<5; i++)
WriteFile(hComm,&byHnd[nCurrentHndShk],1, &lrc, NULL);
//将数据搬到数组中
for (i=0; i<4; i++)
byInputByteData[i] = szInputBuffer[i];
if((byInputByteData[0]&0x80)==0x80)
//负数转换
{
bb[0]=byInputByteData[3];
bb[1]=byInputByteData[2];
bb[2]=byInputByteData[1];//&0x7f);
bb[3]=byInputByteData[0];
lAData=(long)*dw-(long)0x100000000;
}
else
//正数转换
{
bb[0]=byInputByteData[3];
bb[1]=byInputByteData[2];
bb[2]=byInputByteData[1];
bb[3]=byInputByteData[0];
lAData=(long)*dw;
}
dbCurrentValue[nCurrentHndShk] += lAData;
nCount[nCurrentHndShk]++;
} //End ReadFile
}//else Loop
}
else
{
nCuntHndCyc++;
}
break;
case 3:
PurgeComm(hComm, PURGE_RXCLEAR);
nCuntHndCyc = 1;
// for (int i=0; i<5; i++)
WriteFile(hComm,&byHnd[nCurrentHndShk],1, &lrc, NULL);
break;
default:
PurgeComm(hComm, PURGE_RXCLEAR);
nCuntHndCyc = 1;
// for (int i=0; i<5; i++)
WriteFile(hComm,&byHnd[nCurrentHndShk],1, &lrc, NULL);
break;
}//End switch (nCuntHndCyc)
}while (bFlagTerminateThread);
return 0;
}