我的多线程程序:主线程每接收到一个完整的数据包,就启动一个ADO线程.(只用一个连接)

temp 2001-05-10 04:00:00

我打算监视线程从串口每接收到一个数据,发个消息给主线程,
主线程每接收到一个完整的数据包,就启动一个ADO线程,
ADO线程查询后向串口回送命令,怎么样?
(已调通,但不知道有何缺陷)
...全文
189 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
temp 2001-06-16
  • 打赏
  • 举报
回复
谢谢Kevin_qing(Kevin) !
Kevin_qing 2001-06-13
  • 打赏
  • 举报
回复
多线程下面调用API释不会有冲突的,但是如果是调用C/C++函数就有可能。
比如你同时有两个线程读/写同一个文件。。。
所以应该有同步策略
temp 2001-06-13
  • 打赏
  • 举报
回复
<<但创建线程要耗费资源

创建一个线程要耗费多大资源?
ximuwa 2001-06-02
  • 打赏
  • 举报
回复
Kevin_qing(Kevin) :

你的意思是不是多线程下调用api可能会冲突??
Kevin_qing 2001-05-18
  • 打赏
  • 举报
回复
2.因为C/C++库函数本来是为单线程使用的,所以使用了比较多的局部静态变量,而在多线程下面调用会有冲突。
而VC提供了_beginthread()函数就是为了对每个线程做这些静态变量的处理(同步或者是线程独立了)。所以应该使用_beginthread();

当然如果你确信你使用的库函数没有这些问题还是可以用CreateThread的。

3.
用waitforsingleobject()同步好了,至于第二个方法是起不到同步的作用的。

因为可能同时有两个AdoThread()在运行,而这个时候receivestr已经被置空了。

另外 if(receivestr!="")判断有问题。用strcmp函数来比较字符串


conqueror 2001-05-17
  • 打赏
  • 举报
回复
如果每收到一个数据包就起一个线程有点太浪费,要知道同一进程的线程虽然共享资源,但创建线程要耗费资源,线程间切换也是要耗费资源的,如果线程起的太多,cpu大多数时间花在环境切换上那就不爽了,你可以在一开始就创建一个被挂起的线程,每当收到一个完整的数据包唤醒它,处理完数据,再将其挂起,不是更好一些吗?
temp 2001-05-17
  • 打赏
  • 举报
回复
注意回送命令时,写串口要考虑同步。不能两个线程同时写串口。
zheng_rui 2001-05-17
  • 打赏
  • 举报
回复
用但县城多好,何必呢?????????住县城纯粹多余,ado 的m_Connection真能跨县城?????
Kevin_qing 2001-05-17
  • 打赏
  • 举报
回复
这个东西有必要用多线程吗?

简直是画蛇添足
BlowG 2001-05-17
  • 打赏
  • 举报
回复
最好串口的操作由一个县城来干。
temp 2001-05-17
  • 打赏
  • 举报
回复
To Kevin_qing(Kevin) 
(1)
我已经改成了
::CreateThread(NULL,0,ThreadProc,0,0,NULL);
因为dwado本来就没什么用处。

(2)为什么CreateThread()不安全?

(3)
准备加入waitforsingleobject()怎么样?

或者:加入

While(1)
{
if(receivestr!="")
continue;
else break;
}

你看如何?
xyzboat 2001-05-17
  • 打赏
  • 举报
回复
To Kevin_qing(Kevin):
讲的好.
xyzboat 2001-05-17
  • 打赏
  • 举报
回复
/
Kevin_qing(Kevin) . \/
xyzboat 2001-05-17
  • 打赏
  • 举报
回复
/
Kevin_qing(Kevin) . \/

Kevin_qing 2001-05-17
  • 打赏
  • 举报
回复
不是说用线程不好,关键是看有没有必要。
看看你的程序:
1。
CreateThread(NULL,0,AdoThread,0,0,&dwado);
这里有问题,本意是把dwado当参数传给 AdoThread,可是dwado的值不能维持。
可能在AdoThread拿到&dwado时,该地址的值已经改变。
所以这里要么需要同步,要么用其他的方法传值。
改为
CreateThread(NULL,0,AdoThread,0,0,dwado);
2。CreateThread函数不安全,建议改为
_beginthread();
3。...
m_port.WriteToPort(replystr);/*回送命令字符*/

会有冲突。
建议增加一个同步对象


temp 2001-05-17
  • 打赏
  • 举报
回复
<<最好串口的操作由一个县城来干。

为什么?

<<ado 的m_Connection真能跨县城?

我试过呀。可以。


<<如果线程起的太多,cpu大多数时间花在环境切换上那就不爽了

不会太多,一个进程里有7-8个线程总没问题吧。
temp 2001-05-10
  • 打赏
  • 举报
回复
请诸位大虾看看:我这么干有问题吗?
temp 2001-05-10
  • 打赏
  • 举报
回复
部分代码:


_ConnectionPtr m_pConnection;
bool m_fInitialized;


DWORD dwmain;
DWORD dwado;
DWORD WINAPI mainThread(void* p);
DWORD WINAPI AdoThread(void* p);
CSerialPort m_port;



CString receivestr;
CString replystr;

main()
{

... ...

if (FAILED(CoInitialize(NULL)))
m_fInitialized=TRUE;



HRESULT hr;
/*ADO连接数据库*/
try
{
hr = m_pConnection.CreateInstance("ADODB.Connection");/*创建Connection对象*/
if(SUCCEEDED(hr))
{
hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb","","",adModeUnknown);
}
}
catch(_com_error e)/*捕捉异常*/
{
... ...

return FALSE;
}

CreateThread(NULL,0,ThreadProc,0,0,&dwmain);
/*建立主线程*/

if (m_port.InitPort(dwmain, 2, 9600 ))
m_port.StartMonitoring();


... ...

}




DWORD WINAPI ThreadProc(void* p)
{

MSG msg;
while (::GetMessage(&msg, NULL, 0, 0))
{
switch(msg.message)
{

case WM_COMM_RXCHAR:
/*接收到字符*/
receivestr+=char(msg.wParam);
break;

case WM_COMM_CTS_DETECTED:
/*启动数据库查询子线程*/
CreateThread(NULL,0,AdoThread,0,0,&dwado);
receivestr="";
break;

case WM_QUIT:
return 5;

default:
break;
}
}
return 10;
}



DWORD WINAPI AdoThread(void* p)
{

_RecordsetPtr m_pRecordset;
_variant_t vID,vUserID,vUsername,vOld,vBirthday;

try
{
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset->Open("SELECT * FROM users",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
while(!m_pRecordset->adoEOF)
{
vID = m_pRecordset->GetCollect("ID");
vUsername = m_pRecordset->GetCollect("username");
vOld = m_pRecordset->GetCollect("old");
vBirthday = m_pRecordset->GetCollect("birthday");
m_pRecordset->MoveNext();
...
/*在此处理数据*/

}
}
catch(_com_error e)/*捕捉异常*/
{
... ...
}

... ...

m_port.WriteToPort(replystr);/*回送命令字符*/
return 10;
}


void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat)
{

... ...

bResult = ReadFile(port->m_hComm,&RXBuff,1,&BytesRead,&port->m_ov);

... ...

/*把WM_COMM_RXCHAR消息传递给主线程port->m_pOwner*/
::PostThreadMessage(port->m_pOwner, WM_COMM_RXCHAR, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr);

... ...
}

15,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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