MFC的多线程问题:我做了个界面,上面有几个按钮,如查询数据库,显示结果,等。

MFC的多线程问题:我做了个界面,上面有几个按钮,如查询数据库,显示结果,等。,第1张

在VC++中利用MFC编程时,线程被分为工作者线程和用户界面线程两大类。前者用于处理后台任务,执行后台任务并不会耽搁用户对应用程序的使用,即用户 *** 作无需等待后台任务的完成。后者常用来独立的处理用户输入和响应用户事件。

一个工作者线程的实现相当的简单,只需要编写线程控制函数和启动函数就好。启动函数:

CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL )

用户界面线程的实现通常需要派生线程类、重载成员函数和启动用户界面线程。从MFC的CWindThread派生用户界面线程类。父类CWinThread需要重载的函数主要有:InitInstance、ExitInstance和Run。其中InitInstance必须重载,而Run函数除非必要,一般无需重载。其中,启动函数:

CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL )

建议学习Visual C++6.0编程使用技术与案例,看看多线程编程。。。。

用多线程同步技术,即一个线程将要取得数据区锁定,另一个线程此时不能存取此块的数据。

看看多线程同步的书。

例如:

void CCalibPage1::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

UpdateData()

m_nCounter++

double r

CSingleLock sLock(&(gpMainFrm->m_mutex))

sLock.Lock()//此处锁定

double v = gSpindleRevolution

sLock.Unlock()//存取后释放。

if(m_bCalibStart)

{

r = m_CalibValue/v

m_szTestValue0.Format("%f",v)

// m_szTestValue.Format("%f", (v * r))

m_szRatio.Format("%f", r)//

UpdateData(false)

}

else if(m_bVerify)

{

m_szTestValue.Format("%f",v*gcConfig.calib[PCL833_CHANNEL].ratio)

UpdateData(false)

}

if(m_nCounter >30)

{

KillTimer(11)

m_bCalibStart = false

m_bVerify = false

MessageBox(_T("标定完成!"),_T("CNCTest"))

UpdateButtonStatus()

}

CPropertyPage::OnTimer(nIDEvent)

}

参见:

http://baike.baidu.com/view/2808915.htm

1、线程内注册与连接数据库的竞争问题

文档上对多线程下数据库应用的注意事项写的很简明,一个线程创建的 QSqlDatabase 对象和 查出来的 QSqlQuery 对象只能给本线程用(注意,是对象,不是数据库连接本身,连接本身用名字可以多线程使用),其他情况是“不支持的”。在一个需要有几个线程并发访问不同数据库的应用中,我首先试图在各个线程的起始分别以不同的名称调用 addDatabase / database 、open,但是程序偶然会崩溃,跟踪后发现,虽然Qt 声称很多方法是“线程安全”的,但是几个方法串起来,就出问题了。Qt 会动态的加载数据库的plugin, 加载 plug in 的部分,涉及到对本地库文件的管理,这一部分,出现了竞争。于是,很自然的想到在初始连接部分设置 Mutex 保护,从 addDatabase / database到 open 的部分,要保证其原子性,问题再也没有出现。

2、数据库连接意外断裂后,恢复连接的问题

在MFC 中,一旦中途TCP连接断裂,直接重新 Open 就可以了。在Qt 里,这一招不好使了。即便 调用了 close ,再次open 也是不行的。处理方法:

在检测到问题出现后,关闭连接,并 removeDatabase; 而后,不要立刻 addDatabase, 反而是要回到该连接所在的事件循环。没有详细跟源码,很可能在 removeDatabase 后的事件循环中,Qt 内部做了一些释放 *** 作。 怎么办呢, 可以设置一个恢复定时器,比如 1分钟,重新 addDatabase,就可以啦。如果心急的话,直接显式调用processEvent() 方法强制循环。

在多线程下,注意1中的问题,需要 Mutex保护。

3、数据库插件的依赖性问题

在 Windows 下,有时我们的机器上按了好几个 Qt 版本,PATH里索性神马也不设置,依赖开发环境的继承环境适应不同的版本。这有两个问题。一是发布程序的时候,数据库驱动依赖的dll 也要与可执行文件在同一路径下发布。比如 mysql 的 dll, PostgreSQL 的依赖等。二是在集成开发环境中,这些依赖也要位于执行档文件夹下。否则,会造成虽然可以枚举到可用驱动,但是死活连接不上。调试一下就知道,原来是在路径中找不到依赖项,导致dll加载失败哦!


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/10864640.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-11
下一篇2023-05-11

发表评论

登录后才能评论

评论列表(0条)

    保存