高手请进!!关于线程问题,本人在线等候!!!

熬夜程序猴 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);
}

上面的单元没有做任何修改!!!
...全文
40 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
熬夜程序猴 2003-09-12
  • 打赏
  • 举报
回复
我想我的把问题简单化一点!!
有线程 ThreadFZ *FZtest;ThreadCY *CYtest;这两个线程都将对COM3,COM4进行数据采样 但是这两个线程并不是同步的,所以去除共享冲突问题!执行的步骤是这样的
CYtest->执行->终止->FZtest->执行->终止->CYtest->.....
伪代码如下
Button1OnClick(TObject *Sender)
{
if(FZtest!=NULL)
FZtest->Terminate();
//在此进行等待线程FZtest终止
WaitiFor();
if(完全终止)
{
CYtest->执行
}
}
Button2OnClick()
{
if(CYtest!=NULL)
CYtest->Terminate()
WaitFor();
if(完全终止)
FZtest->执行;
}
binbin 2003-09-12
  • 打赏
  • 举报
回复
又开了个贴子?
偶友情UP一下.
gpg 2003-09-12
  • 打赏
  • 举报
回复
别用 TThread,我以前用,现在自己写。比它好多了。
用全局变量同步的话要有互斥量协调。
woainihaha 2003-09-12
  • 打赏
  • 举报
回复
你这样做,如果有并发性的请求(上位机请求),或同一时刻设备响应,你怎么处理??
程序写的再好,也无法改变其硬件本身的特性.你的构架设计的很不合理,也无法扩展,所以才造成你现在的问题,以后的问题还多着呢.
ljyt 2003-09-12
  • 打赏
  • 举报
回复
你为这两个线程写个OnTerminate事件啦。笨……

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧