Ⅰ VC2005 开发一个多线程的应用程序(并发的数据库访问)
对于你的程序,我觉得可以由以下几种改进方法:
1、进程的管理方式可以通过制作一个进程池统一管理(进程池的例子网上不少,搜一下就有)
2、针对数据库的访问是连接多个不同的数据库还是一个?就你说的1分钟完成访问5-6次的话,感觉你的数据库执行效率并不是很高,因此建议你改进一下sql,如果可以用存储过程的话,用存储过程,甚至都可以考虑将很多个SQL拼成一个SQL串一次性执行,这样可以减少数据库的访问次数
3、将需要或者固定下来的东西缓存下来,不要去查
4、尽量在执行一个数据库操作后关闭连接,并释放资源,因为数据库的连接数是有限制的,并且会顺序执行,如果你的操作没有相应完,下一个就来的话,只能先等待上一个做完才可以
5、建议你将执行的存储过程通过SQL的分析器,去计算一下时间,看看SQL是否可以优化
Ⅱ VC多线程访问同一全局变量的问题
WaitForSingleObject(pFrameInQueue->m_mutex,INFINITE);
ReleaseMutex(pFrameInQueue->m_mutex); 需要成对的出现.你在if判断里边释放一次
但是如果if条件不成立,你就没有调用释放.这样的结果就是互斥量mutex被锁定,
其他线程无法调用.
在2个if判断外加上释放mutex的语句再试一试
Ⅲ vc++访问数据库
m_recordset.GetRecordCount()一定是0
这个数目是你访问过的数目.
MoveFrist是没有必要的.
因为打开后,自动会在开始处
建议你看一下我的免费教程(视频\习题\讲义\教材)
VC共享乐园有哦
Ⅳ vc 如何多线程处理CSocket数据
因为CSocket类要用到窗口的消息机制才能进行收发,所以用线程可以这样用的,你可以参考用如下的方法:
CMySocket*
pSocket;
...
ThreadFunc(
)
{
pSocket
=
new
CSocket;
pSocekt->Create();
pSocket->Connect(...);
while(...)
{
MSG
msg;
Sleep(
5
);
if
(
::PeekMessage(&msg,
NULL,
NULL,
NULL,
PM_REMOVE
)
)
{
::TranslateMessage(
&msg
);
::DispatchMessage(
&msg
);
}
。。。
//线程的其他代码
);
}
希望以上的代码对你有用
Ⅳ VC++ 多线程
在进入主消息循环之前创建新的线程,然后把你的回调函数作为参数传递给新建的线程。
这样就可以了,
对于共享资源访问的时候最好是加下锁。
Ⅵ 如何在客户端访问服务器端的数据库(VC++)
1.用数据库自带的客户端管理工具访问修改;
2.去管理工具->数据源,建立数据源,然后再vc中建立一个数据库的工程(Database
project),也可以访问并修改。具体操作可以去网上搜;
3.可以用ODBC或ADO自己编程实现
那就用ODBC写吧,如果是MFC的,用CDATABASE就可以,里面好多方法都有封装,去下载一个ODBC编程的例子看看
Ⅶ vc 如何多线程处理CSocket数据
因为CSocket类要用到窗口的消息机制才能进行收发,所以用线程可以这样用的,你可以参考用如下的方法:
CMySocket*
pSocket;
...
ThreadFunc(
)
{
pSocket
=
new
CSocket;
pSocekt->Create();
pSocket->Connect(...);
while(...)
{
MSG
msg;
Sleep(
5
);
if
(
::PeekMessage(&msg,
NULL,
NULL,
NULL,
PM_REMOVE
)
)
{
::TranslateMessage(
&msg
);
::DispatchMessage(
&msg
);
}
。。。
//线程的其他代码
);
}
希望以上的代码对你有用
Ⅷ VC++多线程问题
据我分析,
1、你的sess因为每个线程都有自己的实例,所以不需要在sess上下临界区
2、目测你的目的是能够并行处理 g_runURL 数组里的地址。这样的话,应该在多个线程间共享那个循环变量i。在创建线程前将i初始化为0,然后将i的地址交给每个线程
3、需要临界区的地方在于循环里的 i++ 而不是处理过程。故临界区应该这样写:
g_cs.Lock();
for(; i < g_runCount; ++i)
{
int thisi = i; //注意要把在临界区内访问到的 i 的值保存在当前线程私有的变量中
g_cs.Unlock();
//这里的代码用到 i 的要换成 thisi
...//你原来的代码
g_cs.Lock();
}
g_cs.Unlock();
Ⅸ 怎样用vc++ 6.0访问SQL Server数据库
从功能简单的数据库(如Jet Engine)到复杂的大型数据库系统(如oracle),VC++6.0都提供了一些编程接口。本文主要介绍以下五种: 1.ODBC API;2.MFC ODBC类;3.MFC DAO类;(数据访问对象)4.MFC的OLE/DB;5.ActiveX数据对象(ADO)。6.RDO远程数据访问
1.开放数据库连接(ODBC API):提供了一个通用的编程接口,允许程序与多种不同的数据库连接。它为Oracle,SQL Server,MS Excel等都提供了驱动程序,使得用户可以使用SQL语句对数据库进行直接的底层功能操作。在使用ODBC API时,用户须引入的头文件为 "sql.h ", "sqlext.h ", "sqltypes.h "。用ODBC API创建数据库应用程序遵循一定的基本步骤:
第一步是分配ODBC环境,使一些内部结构初始化。完成这一步,须分配一个SQLHENV类型的变量在ODBC环境中做句柄使用。
第二步是为将要使用的每一个数据源分配一个连接句柄,由函数SQLALLocHandle()完成。
第三步是使用SQLConnect()把连接句柄与数据库连接,可以先通过SQLSetConnectAttr()设置连接属性。
然后就可以进行SQL语句的操作,限于篇幅,相关的函数就不具体介绍了,读者可以参考相关书籍。
操作完成后,用户取回相应的结果,就可以取消与数据库的连接。
最后需要释放ODBC环境。
ODBC API的特点是功能强大丰富,提供了异步操作,事务处理等高级功能,但相应的编程复杂,工作量大。
2.MFC ODBC类:MFC1.5后的版本里引入封装了ODBC功能的类。通过这些类提供与ODBC的接口,使得用户可以不须处理ODBC API中的繁杂处理就可以进行数据库操作。主要的MFC ODBC类如下。
CDatabase类:一个CDatabase对象表示一个到数据源的连接,通过它可以操作数据源。应用程序可使用多个CDatabase对象:构造一个对象并调用OpenEx()成员函数打开一个连接。接着构造CRecordSet对象以操作连接的数据源,并向CDatabase对象传递记录集构造程序指针。完成使用后用Close()成员函数销毁CDatabase对象。一般情况下并不需要直接使用CDatabase对象,因为CRecordSet对象可以实现大多数的功能。但是在进行事务处理时,CDatabase就起到关键作用。事务(Transaction)指的是将一系列对数据源的更新放在一起,同时提交或一个也不提交,为的是确保多用户对数据源同时操作时的数据正确性。
CRecordSet类:一个CRecordSet对象代表一个从数据源选择的一组记录的集合-记录集。记录集有两种形式:snapshot和dynaset。前者表示数据的静态视图,后者表示记录集与其他用户对数据库的更新保持同步。通过CRecordSet对象,用户可以对数据库中的记录进行各种操作。
CRecordView类:CRecordView对象是在空间中显示数据库记录的视图。这种视图是一种直接连到一个CRecordSet对象的格式视图,它从一个对话框模板资源创建,并将CRecordSet对象的字段显示在对话框模板的控件里。对象利用DDX和RFX机制,使格式上的控件和记录集的字段之间数据移动自动化,也就是说,用户甚至不要编写一行代码就可以实现简单的数据库记录查看程序。
CDBException类:由Cexception类派生,以三个继承的成员变量反映对数据库操作时的异常:
m_nRetCode:以ODBC返回代码(SQL_RETURN)的形式表明造成异常的原因。
m_strError:字符串,描述造成抛出异常的错误原因。
m_strStateNativeOrigin:字符串,用以描述以ODBC错误代码表示的异常错误。
MFC数据库类成员函数都能抛出CDBException类型的异常,所以在代码对数据库进行操作后监测异常是正确做法。
MFC ODBC类在实际开发中应用最广,因为它功能丰富,操作相对简便。
3.MFC DAO(数据访问对象)编程:DAO用于和微软的Access数据库接口。在数据库应用程序如果只需与Access数据库接口时,使用DAO编程较方便。其主要类如下。
CDaoWorkspace:CDaoWorkspace对象可以让一个用户管理从登陆到离开期间,指定的密码保护的数据库会话全过程。大多数情况下不要多个工作区也不要创建明确的工作区对象。因为在打开数据库和记录集对象时,它们可以使用DAO缺省工作区。
CDaoDatabase:代表一个连接,类似上述CDatabase类。
CDaoRecordSet:用来选择记录集并操作,类似上述CRecordSet类。
CDaoRecordView:类似上述CRecordView类。
CDaoException:类似上述CDBException类。
CDaoTableDef:表示基本表或附加表的定义。每个DAO数据库对象包括一个称为TableDef的收集,包含所有存储的DAO表定义对象。CDaoTableDef对象可以用来控制表定义。
CDaoQueryDef:CDaoQueryDef对象表示了一个查询定义(querydef)。
CDaoFieldExchange:支持数据库类使用的DAO字段交换(DFX)例程。也可处理事务,类似MFC ODBC类。
MFC DAO仅用来支持Access数据库,应用范围相对固定。
4.OLE DB:OLE DB在数据提供程序和用户之间提供了灵活的组件对象模型(COM)接口,这种灵活性有时会使得操作复杂化。OLE DB框架定义了应用的三个基本类。
数据提供程序Data Provider:拥有自己的数据并以表格形式显示数据的应用程序。提供OLE DB的行集COM接口,期显示范围可以从单一数据表格的简单提供者知道更复杂的分布式数据库系统。
使用者Consumers:使用OLE DB接口对存储在数据提供程序中的数据进行控制的应用程序。用户应用程序归为使用类。
服务提供程序Service Provider:是数据提供程序和使用者的组合。服务提供程序没有自己的数据,但使用
OLE DB使用者接口来访问存储在数据提供程序中的数据。然后,服务提供程序通过打开数据提供程序接口使得数据对使用者有效。服务提供程序常用于向应用程序提供高层次服务,比如高级分布式查询。
OLE DB编程时,用户使用组件对象开发应用程序。这些组件有:
枚举器:用于列出可用的数据源;
数据源:代表单独的数据和服务提供程序,用于创建对话;
对话:用于创建事务和命令;
事务:用于将多个操作归并为单一事务处理;
命令:用于向数据源发送文本命令(SQL),返回行集;
错误:用于获得错误信息。
5.ActiveX数据对象(ADO):是微软提供的面向对象的接口,与OLE DB类似,但接口更简单,具有更广泛的特征数组和更高程度的灵活性。ADO基于COM,提供编程语言可利用的对象,除了面向VC++,还提供面向其他各种开发工具的应用,如VB,VJ等。ADO在服务器应用方面非常有用,特别是对于动态服务器页面ASP(Active Server Page)。
ADO对象结构类似于OLE DB,但并不依靠对象层次。大多数情况下,用户只需要创建并只使用需要处理的对象。下面的对象类组成了ADO接口。
Connection:用于表示与数据库的连接,以及处理一些命令和事务。
Command:用于处理传送给数据源的命令。
Recordset:用于处理数据的表格集,包括获取和修改数据。
Field:用于表示记录集中的列信息,包括列值和其他信息。
Parameter:用于对传送给数据源的命令之间来回传送数据。
Property:用与操作在ADO中使用的其他对象的详细属性。
Error:用于获得可能发生的错误的详细信息。
在VC++使用ADO需要进行COM操作,详细方法在此就不赘述了。
在当今流行的分布式开发环境下,VC++6.0在数据库开发方面有较强的优势,学会
在不同的场合选用不同的技术,对开发人员来说是必要的技术。
Ⅹ VC多线程访问数据库的数据传递问题
说一些概念性的东西吧。
COM操作,它有一套自己关于跨线程和跨进程的模型,这是个复合模型,会衍生出大约7,8种组合。学习COM,这个是一定要吃透的。楼主阅读一下关于CoInitializeEx函数的帮助文档,能多多少少体会到一些。但如果没学习过COM,光看MSDN的帮助文档,如坠云里雾里一般,很难理解的。因此,建议买本COM的书,稍微参阅一下,其次网上譬如CSDN中有很多热心人写的关于线程进程有关的COM模型,和使用规则,优缺点,可以拜读一下!
在MFC中,可能不太会形成跨线程传递变量的危害性,这种观念吧。所以,在MFC中,似乎我们能随心所欲在线程之间传递变量,但其实是不对的,典型的就是主线程创建的窗口和控件,最好不要在其它线程中直接操纵,而是通过线程间通信的方法,让创建窗口和控件的主线程来操纵窗口和控件。
因此,变量是不能乱传地,到了COM中,这个限制是非常明显的,COM中有概念叫MARSHAL、PROXY、STUB,当然它主要是进程相关的概念,同样说明了,非线程自己创建的东西,不是该线程使用就会有问题。
像VIEW这种界面的东西不要随便乱传给工作线程这种非界面线程。
我的建议是:
建工作线程,因为数据库操作及从数据库反馈到程序级的数据需要进行再加工,这些步骤都可能会非常耗时,耗时操作放在界面线程,会使界面线程无法处理WM_XXX的消息,造成界面假死。因此,像智能指针这种东西放到工作线程里进行独立管理,工作线程通过智能指针向数据库要数据,然后处理,存放数据结果到程序中约定的地方,如全局变量,虚拟内存等地方。数据处理完,通过自定义消息,向界面线程发送自定义消息,使界面线程能够在自定义消息中,将保存的数据显示到界面中,发送线程消息有个函数就是PostThreadMessage。
其他的细微细节也可以考虑,到底是创建自己的线程,还是使用线程池等。随着经验的丰富,会考虑很多问题的,关键是理论知识要学,实践也不能没有。
最后就是概念修正, _ConnectionPtr它是一个标准的C++类,C++类可以重载->操作符,这个被重载的指针操作符,使得通过该类实例化的变量在实际使用时,行为更像是一个指针,而不是个普通变量,这个被重载的指针操作符才是智能指针,而不是指_ConnectionPtr类是智能指针,顶多说它是个智能指针类,我也见过有翻译成灵巧指针的,英文原版是SMART POINTER。