如何带参数启动线程?

jukyy 2003-04-14 10:34:22
是这样的,我要用多线程与十多个串口进行实时通信,如果每个串口对应写一个线程,那么要写十几个线程。而用同一个线程(同一段代码)去启动十多次的话,必须每次分别对应不同的串口,这个问题如何实现,请大虾们指点。一定给分!
以下是线程的Execute方法:
void __fastcall ThreadComm::Execute()
{
DWORD dwEvtMask,dwTransfer;
OVERLAPPED os;
memset(&os,0,sizeof(OVERLAPPED));
os.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(!SetCommMask(fmain->COMX->hCom,EV_RXCHAR|EV_TXEMPTY)) //这里用到了主FORM的对象(其中通讯对象实例COMX = new TCommunication();HANDLE hCom;)
{
MessageBox(NULL,"设置通信设备控制块数据结构操作异常!","错误",MB_OK);
return;
}
while(!Terminated)
{
dwEvtMask=0;
if (!WaitCommEvent(fmain->COMX1->hCom, &dwEvtMask, &os)) //也用到了
{
if(GetLastError()==ERROR_IO_PENDING)
{
if(GetOverlappedResult(fmain->COMX1->hCom,&os,&dwTransfer,TRUE))//;
os.Offset+=dwTransfer;
}
}
if ((dwEvtMask & EV_RXCHAR)==EV_RXCHAR)
{
recvBuffer=fmain->COMX1->ReceiveProcess();
if(!recvBuffer.IsEmpty())
{
Synchronize(AddToMemo);
}
}
if((sendCount>0)&&((dwEvtMask & EV_TXEMPTY)==EV_TXEMPTY))
{
SendOneByte();
}
}
MessageBox(NULL,"线程终止!","信息",MB_OK);
}

在主进程中我想实现
pThread1 = new ThreadComm(false);
pThread2 = new ThreadComm(false);
pThread3 = new ThreadComm(false);
……
pThread18 = new ThreadComm(false);
这样的模式,不知可行否?或者有没有其他的方法?


...全文
123 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
BCB 2003-04-14
  • 打赏
  • 举报
回复
两种办法:
1. 线程构造函数可以任意加参数;
(1) 给线程多加一些自定义属性当参数:
(2)在构造函数体中,将参数送给自定义的属性;


2。 (1)给线程多加一些自定义属性当参数:
(2)new 线程;先不要运行;
(3)设你的属性,就是你的参数了;
(4)运行线程;
jishiping 2003-04-14
  • 打赏
  • 举报
回复
对于TCommunication *COMX1;的错误,在头文件里包含定义TCommunication的头文件就可以
了。对于ThreadComm的定义,存在2个class互相包含的问题,此时的解决办法有2个:一是将
上面的ThreadComm改成TThread就可以了;二是这样写:

#include "xxxx.h" //这儿的xxxx.h就是TCommunication2所在的头文件

class ThreadComm; //这儿先描述一样
class TMainForm : public TForm
{
__published: // IDE-managed Components
//.......
private: // User declarations
ThreadComm *pThread1; //有了上面的描述,这儿就没有错误了
//......
public:
//......
};

另外,需要在MainForm.cpp 的开头,包含class ThreadComm 所在的头文件。对于
TCommunication2,也可以采用ThreadComm的做法。
jukyy 2003-04-14
  • 打赏
  • 举报
回复
To jishiping(JSP 季世平) :
我在主FORM的头文件里定义的

private: // User declarations
ThreadComm *pThread1; //编译出错E2303 Type name expected
//编译出错E2139 Declaration missing
// ThreadComm2 *pThread2;

public: // User declarations
TCommunication *COMX1; //编译出错E2303 Type name expected
//编译出错E2139 Declaration missing
// TCommunication2 *COMX2;

这两个地方应该怎么定义呢?




chinayang 2003-04-14
  • 打赏
  • 举报
回复
用修改Thread类中的构造函数.也是可以的.
jukyy 2003-04-14
  • 打赏
  • 举报
回复
谢谢jishiping(JSP 季世平) 大虾,我试试先。
jishiping 2003-04-14
  • 打赏
  • 举报
回复
其实在你的上面那个ThreadComm::Execute()里,对应不同的端口的操作,变化的就是
fmain->COMX1这个参数。所以,你的class ThreadComm 这样定义:
class ThreadComm : public TThread
{
protected:
TCommunication* COMX;

void __fastcall Execute();
//......其它的函数,及其它的变量
public:
__fastcall ThreadComm(TCommunication* comx)
};

__fastcall ThreadComm::ThreadComm(TCommunication* comx)
: TThread(false), COMX(comx)
{
}

//所有的fmain->COMX1换成COMX就可以了
void __fastcall ThreadComm::Execute()
{
DWORD dwEvtMask,dwTransfer;
OVERLAPPED os;

memset(&os,0,sizeof(OVERLAPPED));
os.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(!SetCommMask(COMX->hCom,EV_RXCHAR|EV_TXEMPTY))
{
MessageBox(NULL,"设置通信设备控制块数据结构操作异常!","错误",MB_OK);
return;
}
while(!Terminated)
{
dwEvtMask=0;
if (!WaitCommEvent(COMX->hCom, &dwEvtMask, &os))
{
if(GetLastError()==ERROR_IO_PENDING)
{
if(GetOverlappedResult(COMX->hCom,&os,&dwTransfer,TRUE))//;
os.Offset+=dwTransfer;
}
}
if ((dwEvtMask & EV_RXCHAR)==EV_RXCHAR)
{
recvBuffer=COMX->ReceiveProcess();
if(!recvBuffer.IsEmpty())
{
Synchronize(AddToMemo);
}
}
if((sendCount>0)&&((dwEvtMask & EV_TXEMPTY)==EV_TXEMPTY))
{
SendOneByte();
}
}
MessageBox(NULL,"线程终止!","信息",MB_OK);
}

在fmain里调用时,
pThread1 = new ThreadComm(COMX1);
pThread2 = new ThreadComm(COMX2);
如果不是在fmain里调用,就将上面的COMX1换成fmain->COMX1,COMX2换成fmain->COMX2。
jishiping 2003-04-14
  • 打赏
  • 举报
回复
ComPort 是参数,指定哪个端口,而m_ComPort是class m_ComPort的一个成员变量。
jukyy 2003-04-14
  • 打赏
  • 举报
回复
wt_sanlian(雷电®) :
麻烦解答一下上面的问题啦,另外在线程的Execute方法里也有用到主FORM的变量,怎么办?
jukyy 2003-04-14
  • 打赏
  • 举报
回复
在构造函数里加上
m_ComPort = ComPort;
是什么意思呀?ComPort在哪定义?
wt_sanlian 2003-04-14
  • 打赏
  • 举报
回复
在ThreadComm类中加一个成员,AnsiString m_ComPort;
将ThreadComm的构造函数改一下,加一个参数
ThreadComm::ThreadComm(bool, AnsiString ComPort)
{
m_ComPort = ComPort;
}
wetrust 2003-04-14
  • 打赏
  • 举报
回复
定义线程时就给构造函数多家一个参数用于传递参数,如ThreadComm(CreateSuspend,MyParam)
jukyy 2003-04-14
  • 打赏
  • 举报
回复
To jishiping(JSP 季世平) :
1.头文件已经是包括进了的,在改动之前程序是可以编译运行的。
2.将ThreadComm改成TThread肯定不行呀,因为ThreadComm是我定义的线程派生类,改成TThread后我自己写的函数都用不成了。
3.我按照你的办法添加类说明
class ThreadComm;
class TCommunication;
就一切OK了。感谢你的鼎立相助。马上结贴!
另外也谢谢 BCB(天下三分明月夜,二分无赖是扬州) !

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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