高手请进!!关于线程问题,本人在线等候!!!
熬夜程序猴 2003-09-12 08:29:13 我现在正在开发《多任务电机测试系统》,在线程的使用中碰到了几个很严重的问题,希望高手给我指点迷津!!
问题1:
如何实现进程与线程之间的通信?据我所掌握的知识知道,Process 与 Thread的通信有全局变量、参数传递、共享内存、消息传递(只适合 Thread 向 Process 发送,反之则不行,因为Thread有消息循环),全局和共享内存存在共享冲突问题,我能解决但是不是我现在所做项目所需要的,而参数传递则牵强人意!不知道各位高手是否有更理想的解决方法呢?望赐教!!
问题2:
如何知道Thread的结束,即终止乃至消亡?我是用C++ Builder的TThread类实现线程的,代码如下:
//窗体代码—***********************
/---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TThrTest *test;//线程派生
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
test=new TThrTest(false);//启动线程
test->AssignLabel(Label1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
test->Terminate();//终止线程
int k=test->WaitFor();等待线程结束
if(k==3)//线程结束返回码
Label1->Caption="The \'test\' Thread is Terminated.";
}
//---------------------------------------------------------------------------
//线程代码
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#include "TComObjectUnit.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
TComObject *ComObject;//自封装的一个串口通讯类(初始化,联机,采样,……)
__fastcall TThrTest::TThrTest(bool CreateSuspended)
: TThread(CreateSuspended)
{
ReturnValue=3;//线程结束返回码
UpdateLabel=NULL;
ComObject=new TComObject(1,3,4,"ZCKB0.575(交流系统)");
//1,测试系统类型(交流还是直流);3,4 为串口COM3,COM4;“ZCKB0.575(交流系统)”为测功机类型
ComObject->Start_DJ(1,4);//启动电机
ComObject->SendMSG(3,CUSTTEST_COMMAND);//向下位机发送测试命令
}
//---------------------------------------------------------------------------
void __fastcall TThrTest::Execute()
{
while(!Terminated)
{
//
DWORD T1=::GetTickCount();
this->Synchronize(UpdateLB);//数据采样、同步刷新
do
{
Application->ProcessMessages();
}while((::GetTickCount()-T1)<500);//每采样一次为500MS
}
}
//---------------------------------------------------------------------------
void __fastcall TThrTest::UpdateLB()
{
ComObject->CustCY(3,4);//采样
UpdateLabel->Caption=FormatFloat("0.0000",ComObject->ZJ_buf);//格式化输出转矩值
}
void __fastcall TThrTest::AssignLabel(TLabel *LB)
{
UpdateLabel=LB;
}
问题是在终止中时而有用,时而没有(进入永久等待)
而在我的系统中则完全是等待!!
请高手给予分析!!!
以下是TComObject类的主要的采样方法贴上
//=============== 手动测试数据采样 ===================
int __fastcall TComObject::CustCY(int port_c,int port_i)
{
//TODO: 手动采样
int c_p=port_c;
int i_p=port_i;
return this->DataCY(AC_Mode,c_p,i_p,SDCY_COMMAND/*采样命令*/);
}
////===============TComObject 封装的测试过程 数据采样===================
int __fastcall TComObject::DataCY(int Mode,int C_port,int I_port,BYTE Command/*采样命令*/)
{
//TODO: 数据采样
//AC_Mode:电机模式:1,交流、0,直流
//typedef AC_LOCK_COMMAND Lock; //数据锁定
int count=0,tmp=0;
int len1,len2;
BYTE buf1[12],buf2[12],_buf1[12],_buf2[12];
/*memset(buf1,0,12);
memset(buf2,0,12);
memset(_buf1,0,12);
memset(_buf2,0,12);*/
AC_Mode=Mode;
//IsBusyed = true;//正在数据采样
switch(AC_Mode)
{
case 0:
break;
case 1://系统类型(1为交流)
//发送采样命令字
do
{
sio_flush(C_port,2);//Control ,清缓冲区
int ret=sio_putch(C_port,Command );//采样命令
if(ret==-4)
{
//error
ErrMsg("采样命令发送出错,本次测试退出!");
return TEST_FAIL;
//;stop Thread
}
_Delay(100);//原Delay(100) //延时
sio_flush(I_port,2);//AC
ret=sio_putch(I_port,AC_SEND_COMMAND);//采样命令
if(ret==-4)
{
//error
ErrMsg("采样命令发送出错,本次测试退出!");
return TEST_FAIL;
//;stop Thread
}
_Delay(50);//原 Delay(50);
do
{
_Delay(2);//Delay(50);
int k=sio_iqueue(C_port);//查询缓冲区的数据个数
int j=sio_iqueue(I_port);
if(k<6 || j<12)
{
tmp++;
if(tmp>=19)
{
count++;
if(count>2)
return TEST_FAIL;
}
}
else
{
tmp=0;
break;
}
}while(tmp<20);
sio_read(C_port,buf1,6);//read Control
sio_read(I_port,buf2,12);//read AC
if(buf1[5]==Command )
{
_buf1[0]=buf1[0];
_buf1[1]=buf1[1];
ZJ_buf=getZJvalue(_buf1);
_buf1[0]=buf1[2];
_buf1[1]=buf1[3];
_buf1[2]=buf1[4];
ZS_buf=getZSvalue(_buf1);
SCGL_buf=getSCGLvalue(ZS_buf,ZJ_buf);
}
else
{
ErrMsg("电量仪参数获取出错,本次测试退出!");
return TEST_FAIL;
}
if(buf2[0]==AC_SEND_COMMAND)
{
_buf2[0]=buf2[1];
_buf2[1]=buf2[2];
_buf2[2]=buf2[3];
DY_buf=getDYvalue(_buf2,AC_Mode,1);
_buf2[0]=buf2[4];
_buf2[1]=buf2[5];
_buf2[2]=buf2[6];
DL_buf=getDLvalue(_buf2,AC_Mode,2);
_buf2[0]=buf2[7];
_buf2[1]=buf2[8];
_buf2[2]=buf2[9];
SRGL_buf=getSRGLvalue(_buf2,0,0,AC_Mode);
_buf2[0]=buf2[10];
_buf2[1]=buf2[11];
GLYS_buf=getGLYSvalue(_buf2);
XL=getXLvalue(SRGL_buf,SCGL_buf,AC_Mode);
return TEST_SUCCEED;
//break;
}
else
{
ErrMsg("电量仪参数获取出错,本次测试退出!");
return TEST_FAIL;
}
}while(count<3);
break;
}
return TEST_SUCCEED;
}
void Delay(DWORD MS)//原
{
DWORD T1,T2,T3;
T1=::GetTickCount();
do
{
T2=::GetTickCount();
T3=T2-T1;
if(T3<MS)
Application->ProcessMessages();
}while(T3<MS);
}
void _Delay(DWORD MS)//修改后
{
DWORD T1,T2,T3;
T1=::GetTickCount();
do
{
T2=::GetTickCount();
T3=T2-T1;
//if(T3<MS)
//Application->ProcessMessages();
}while(T3<MS);
}
上面的单元没有做任何修改!!!