资源预览内容
第1页 / 共5页
第2页 / 共5页
第3页 / 共5页
第4页 / 共5页
第5页 / 共5页
亲,该文档总共5页全部预览完了,如果喜欢就下载吧!
资源描述
vb实现多线程!2006年10月17日星期二上午01:052:30的时候还没睡着,觉得有必要把vb编写多线程程序再次写一次;主要是以前忽略的细节和重要的环节;今天在公司打开一年多没用的vb,写了如下的代码;想写多线程的朋友可以调试一下看看,关于多线程的任务模式,同步和互斥,临界资源和.昨晚2:30的时候还没睡着,觉得有必要把vb编写多线程程序再次写一次;主要是以前忽略的细节和重要的环节;今天在公司打开一年多没用的vb,写了如下的代码;想写多线程的朋友可以调试一下看看,关于多线程的任务模式,同步和互斥,临界资源和临界区(文中提到)欢迎跟帖讨论;请将该部分数据保存为FORM1.frm文件VERSION5.00 多线程 = 3195=60= 345= 6450= Form1= 3195= 64503 窗口缺省BeginVB.FormForm1CaptionClientHeightClientLeftClientTopClientWidthLinkTopicScaleHeightScaleWidthStartUpPosition=Height=270Left=960TabIndex=2Text=2Top=2760BeginVB.TextBoxText1Width=2415EndBeginVB.CommandButtonCommand2Caption=返回Height=255Left=3480TabIndex=1Top=2760Width=1455EndBeginVB.CommandButtonCommand1Caption=StartCountHeight=255Left=3480TabIndexTop=240Width=1455EndBeginVB.LabelLabel1AutoSize=-1True.11Caption=主线程执行结果测试Height=180Left=600TabIndex=3Top=2400Width=1710EndEndAttributeVB_Name=Form1AttributeVB_GlobalNameSpace=FalseAttributeVB_Creatable=FalseAttributeVB_PredeclaredId=TrueAttributeVB_Exposed=FalsePrivateSubCommand1_Click()声明了线程IDDimthreadid1AsLongDimthreadid2AsLong参数一,lpThreadAttributes线程安全属性,传递为NULL参数二,dwStackSize,线程堆栈大小,可以为0,表示堆栈和此应用堆栈相同参数三,lpstartAddress,执行函数地址,用AddressOf获取参数四,lpParameter,执行函数的参数地址,可以是一个记录或者是别的类型,用VarPtr获取参数地址(varptr为未公开函数)!参数五,dwCreationFlags,表示线程创建后的状态!,0表示立即运行,create_SUSPENDED示线程挂起参数六,lpThreadID表示分配给线程的线程号CallCreateThread(Null,ByValO&,AddressOfModule1.OutText1,VarPtr(0),ByVal0&,threadid1)CallCreateThread(Null,ByVal0&,AddressOfModule1.OutText2,VarPtr(0),ByVal0&,threadid2)EndSubPrivateSubCommand2_Click()该事件运行于主线程!DimiAsLong不要点击次数太多,LONG类型会溢出i=CLng(Text1.Text)Text1.Text=CStr(i*i)EndSubPrivateSubForm_Load()保存窗体句柄全局变量,用于在form上绘图formhandle=Form1.hwndEndSub请将该部分数据保存为Module1.bas文件AttributeVB_Name=Module1线程安全属性数据结构;PublicTypeSECURITY_ATTRIBUTESnLengthAsLonglpSecurityDescriptorAsLongbInheritHandleAsLongEndType这个是用于多线程访问临界资源同步Api的数据结构PublicTypeCRITICAL_SECTIONdummyAsLongEndType为什么用GDI函数绘图?原因等下再讲PublicDeclareFunctionGetDCLibuser32(ByValhwndAsLong)AsLongPublicDeclareFunctionSetBkColorLibgdi32(ByValhdcAsLong,ByValcrColorAsLong)AsLongPublicDeclareFunctionTextOutLibgdi32AliasTextOutA(ByValhdcAsLong,ByValxAsLong,ByValyAsLong,ByVallpStringAsString,ByValnCountAsLong)AsLongPublicDeclareFunctionReleaseDCLibuser32(ByValhwndAsLong,ByValhdcAsLong)AsLong请注意;createThreadAPi声明已被我修改过,修改的地方请自行参照APIView复制的内容PublicDeclareFunctionCreateThreadLibkernel32(lpThreadAttributesAsAny,ByValdwStackSizeAsLong,ByVallpStartAddressAsLong,ByVallpParameterAsLong,ByValdwCreationFlagsAsLong,lpThreadIdAsLong)AsLong这个是sleep,作用就是让两个线程绘图频率不一致,效果才明显。PublicDeclareSubSleepLibkernel32(ByValdwMillisecondsAsLong)PublicDeclareSubEnterCriticalSectionLibkernel32(lpCriticalSectionAsCRITICAL_SECTION)进入临界区PublicDeclareSubLeaveCriticalSectionLibkernel32(lpCriticalSectionAsCRITICAL_SECTION)离开临界区几个重要的函数举例ObjPtr:返回对象实例私有域的地址。StrPtr:返回字符串第一个字的地址。VarPtr:返回变量的地址。全局的form的句柄!PublicformhandleAsLong临界数据结构PublicsectAsCRITICAL_SECTIONSubOutText1()过程一DimiAsLongDimdcAsLongDimsAsStringdc=GetDC(formhandle)获取窗体句柄的DCFori=1To100000s=CStr(i)CallSetBkColor(dc,&HF0F0F0)设置绘制区域的背景色,也起清除作用CallTextOut(dc,10,10,s,Len(s)输出文本!CallSleep(40)等待NextCallReleaseDC(formhandle,dc)释放资源!CallEnterCriticalSection(sect)上下表示该处为临界区,如果要对工程全局变量做操作,最好在该区域内否则线程同步过程中,非常容易让程序崩溃CallLeaveCriticalSection(sect)EndSubSubOutText2()和过程一类似DimiAsLongDimdcAsLongDimsAsStringdc=GetDC(formhandle)Fori=1To100000s=CStr(i)CallSetBkColor(dc,&HF0F0F0)CallTextOut(dc,10,80,s,Len(s)文本位置改变了CallSleep(20)延时改变了NextCallReleaseDC(formhandle,dc)CallEnterCriticalSection(sect)CallLeaveCriticalSection(sect)EndSub关于为何使用gdi函数输出文本,这是一个很重要的内容;程序在记数时用了难用的TextOut函数,而没有使用标签控件,这是因为vb的组件不都是线程安全的,当多线程访问不是线程安全的组件,那么会产生严重错误。
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号