createthread函数例子.docx

上传人:b****8 文档编号:11947090 上传时间:2023-06-03 格式:DOCX 页数:11 大小:18.34KB
下载 相关 举报
createthread函数例子.docx_第1页
第1页 / 共11页
createthread函数例子.docx_第2页
第2页 / 共11页
createthread函数例子.docx_第3页
第3页 / 共11页
createthread函数例子.docx_第4页
第4页 / 共11页
createthread函数例子.docx_第5页
第5页 / 共11页
createthread函数例子.docx_第6页
第6页 / 共11页
createthread函数例子.docx_第7页
第7页 / 共11页
createthread函数例子.docx_第8页
第8页 / 共11页
createthread函数例子.docx_第9页
第9页 / 共11页
createthread函数例子.docx_第10页
第10页 / 共11页
createthread函数例子.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

createthread函数例子.docx

《createthread函数例子.docx》由会员分享,可在线阅读,更多相关《createthread函数例子.docx(11页珍藏版)》请在冰点文库上搜索。

createthread函数例子.docx

createthread函数例子

createthread函数例子

篇一:

CreateThread用法详解

CreateThread用法详解

今天我给大家讲一讲C++中的多线程编程技术,C++本身并没有提供任何多线程机制,但是在window下,我们可以调用SDKwin32api来编写多线程的程序,下面我就此简单的讲一下:

创建线程的函数

HANDLECreateThread(

LPSECURITY_ATTRIBUTESlpThreadAttribute,//SD

SIZE_TdwStackSize,//initialtackize

LPTHREAD_START_ROUTINElpStartAddre,//threadfunction

LPVOIDlpParameter,//threadargument

DWORDdwCreationFlag,//creationoption

LPDWORDlpThreadId//threadidentifier

);

在这里我们只用到了第三个和第四个参数,第三个参数传递了一个函数的地址,也是我们要指定的新的线程。

第四个参数是传给新线程的参数指针

eg1:

#include

#include

uingnamepacetd;

DWORDWINAPIFun(LPVOIDlpParamter)

{

while

(1){cout<<"Fundiplay!

"<

}

intmain()

{

HANDLEhThread=CreateThread(NULL,0,Fun,NULL,0,NULL);

CloeHandle(hThread);

while

(1){cout<<"maindiplay!

"<

return0;

}

我们可以看到主线程(main函数)和我们自己的线程(Fun函数)是随机地交替执行的,但是两个线程输出太快,使我们很难看清楚,我们可以使用函数

VOIDSleep(

);

来暂停线程的执行,dwMilliecond表示千分之一秒,所以

Sleep(1000);

表示暂停1秒

eg2:

#include

#include

uingnamepacetd;

DWORDWINAPIFun(LPVOIDlpParamter)

{

while

(1){cout<<"Fundiplay!

"<

}

intmain()

{

HANDLEhThread=CreateThread(NULL,0,Fun,NULL,0,NULL);

CloeHandle(hThread);

while

(1){cout<<"maindiplay!

"<

return0;

}

执行上述代码,这次我们可以清楚地看到在屏幕上交错地输出Fundiplay!

和maindiplay!

,我们发现这两个函数确实是并发运行的,细心的读者可能会发现我们的程序是每当Fun函数和main函数输出内容后就会输出换行,但是我们看到的确是有的时候程序输出换行了,有的时候确没有输出换行,甚至有的时候是输出两个换行。

这是怎么回事?

下面我们把程序改一下看看:

eg3:

#include

#include

uingnamepacetd;

DWORDWINAPIFun(LPVOIDlpParamter)

{

while

(1){cout<<"Fundiplay!

\n";Sleep(1000);}

}

intmain()

{

HANDLEhThread=CreateThread(NULL,0,Fun,NULL,0,NULL);

CloeHandle(hThread);

while

(1){cout<<"maindiplay!

\n";Sleep(2000);}

return0;

}

我们再次运行这个程序,我们发现这时候正如我们预期的,正确地输出了我们想要输出的内容并且格式也是正确的。

下面我就来讲一下此前我们的程序为什么没有正确的运行。

多线程的程序时并发地运行的,多个线程之间如果公用了一些资源的话,我们并不能保证这些资源都能正确地被利用,因为这个时候资源并不是独占的,举个吧:

eg4:

加入有一个资源inta=3

有一个线程函数elfAdd()该函数是使a=a+a

又有一个线程函数elfSub()该函数是使a=a-a

我们假设上面两个线程正在并发欲行,如果elfAdd在执行的时候,我们的目的是想让a编程6,但此时elfSub得到了运行的机会,所以a变成了0,等到elfAdd的到执行的机会后,a=a+a,但是此时a确是0,并没有如我们所预期的那样的到6,我们回到前面eg2,在这里,我们可以把屏幕看成是一个资源,这个资源被两个线程所共用,加入当Fun函数输出了Fundiplay!

后,将要输出endl(也就是清空缓冲区并换行,在这里我们可以不用理解什么事缓冲区),但此时main函数确得到了运行的机会,此时Fun函数还没有来得及输出换行就把CPU让给了main函数,而这时main函数就直接在Fundiplay!

后输出maindiplay!

,至于为什么有的时候程序会连续输出两个换行,读者可以采用同样的分析方法来分析,在这里我就不多讲了,留给读者自己思考了。

那么为什么我们把eg2改成eg3就可以正确的运行呢?

原因在于,多个线程虽然是并发运行的,但是有一些操作是必须一气呵成的,不允许打断的,所以我们看到eg2和eg3的运行结果是不一样的。

那么,是不是eg2的代码我们就不可以让它正确的运行呢?

答案当然是否,下面我就来讲一下怎样才能让eg2的代码可以正确运行。

这涉及到多线程的同步问题。

对于一个资源被多个线程共用会导致程序的混乱,我们的解决方法是只允许一个线程拥有对共享资源的独占,这样就能够解决上面的问题了。

HANDLECreateMute某(

LPSECURITY_ATTRIBUTESlpMute某Attribute,//SD

BOOLbInitialOwner,//initialowner

LPCTSTRlpName//objectname

);

该函数用于创造一个独占资源,第一个参数我们没有使用,可以设为NULL,第二个参数指定该资源初始是否归属创建它的进程,第三个参数指定资源的名称。

HANDLEhMute某=CreateMute某(NULL,TRUE,"creen");

这条语句创造了一个名为creen并且归属于创建它的进程的资源

BOOLReleaeMute某(

HANDLEhMute某//handletomute某

);

该函数用于释放一个独占资源,进程一旦释放该资源,该资源就不再属于它了,如果还要用到,需要重新申请得到该资源。

申请资源的函数如下

DWORDWaitForSingleObject(

HANDLEhHandle,//handletoobject

);

第一个参数指定所申请的资源的句柄,第二个参数一般指定为INFINITE,表示如果没有申请到资源就一直等待该资源,如果指定为0,表示一旦得不到资源就返回,也可以具体地指定等待多久才返回,单位是千分之一秒。

好了,该到我们来解决eg2的问题的时候了,我们可以把eg2做一些修改,如下

eg5:

#include

#include

uingnamepacetd;

HANDLEhMute某;

DWORDWINAPIFun(LPVOIDlpParamter)

{

while

(1){

WaitForSingleObject(hMute某,INFINITE);

cout<<"Fundiplay!

"<

Sleep(1000);

ReleaeMute某(hMute某);

}

}

intmain()

{

HANDLEhThread=CreateThread(NULL,0,Fun,NULL,0,NULL);

hMute某=CreateMute某(NULL,FALSE,"creen");

CloeHandle(hThread);

while

(1){

WaitForSingleObject(hMute某,INFINITE);

cout<<"maindiplay!

"<

Sleep(2000);

}

return0;

}

运行代码正如我们所预期的输出了我们想要输出的内容。

好了,终于讲完

篇二:

线程函数CreateThread的使用

线程函数CreateThread的使用

HANDLEWINAPICreateThread(

__in_optLPSECURITY_ATTRIBUTESlpThreadAttribute,//指向SECURITY_ATTRIBUTES的指针,为新线程指定安全描述

__inSIZE_TdwStackSize,//初始化线程堆栈尺寸

__inLPTHREAD_START_ROUTINElpStartAddre,//线程函数所指向的地址起始函数__in_optLPVOIDlpParameter,//给线程函数传递的参数

__inDWORDdwCreationFlag,//有关线程的标志

__out_optLPDWORDlpThreadId//系统分配给线程的ID

);

----第一个参数是安全属性,一般设为nil,使用缺省的安全属性。

当我们想此线程有另外的子进程时,可改变它的属性。

----第二个参数是线程堆栈尺寸,一般设为0,表示与此应用的堆栈尺寸相同,即主线程与创建的线程一样长度的堆栈。

并且其长度会根据需要自动变长。

----第四个参数是你需要向线程函数传递的参数,一般是一个指向结构的指针。

不需传递参数时,则这个参数设为nil。

----第五个参数,传入与线程有关的一些标志,如果是CREATE_SUSPENDED,则创建一个挂起的线程,即这个线程本身已创建,它的堆栈也已创建。

但这个线程不会被分配给CPU时间,只有当ReumeThread函数被调用后才能执行;当然,也可以调用SupendThread函数再次挂起线程。

要是标志为0,那么一旦建立线程,线程函数就被立即调用。

一般传为0即可。

----第六个参数是系统分配给这个线程的唯一的ID标志

举例:

DWORDWINAPIThread1Proc(LPVOIDargv)

{

cout<<"Thread1Func\n";

return0;

}

intmain()

{

HANDLEThread;

DWORDThreadID;

Thread1=CreateThread(

0,//默认安全级别

0,//堆栈大小默认(2M)

ThreadProc,//线程入口函数

0,//参数没有

0,//创建时的状态

&Thread1ID//获得线程ID);

cout<<"main\n";

Sleep(100);

return0;

}

篇三:

CreateThread函数解析

随着时代的发展,计算机技术发展得很快。

CPU已经从单核心到多核心的转变,也就是一个CPU里具备了同时做多件事情的能力,而不是过去的分时复用了,而是实实在在地做多件事情。

因此,开发软件也进入了一个新时代,就是多线程软件的开发时代。

如何合理地分配多个线程同时运行,是提高软件效率的关键因素了。

比如像网络游戏的客户端里,就可以使用一个线程不断地更新游戏的界面,分配另外一个线程不断地发送和接收网络的数据,这样CPU的两个核心都在不断地工作。

如果还像以前那样使用一个线程的话,就会发现只有一个内核在做事情。

当然使用线程的编程模型,也会大大地简化软件的复杂性。

下面就来使用线程的API函数。

函数CreateThread声明如下:

WINBASEAPI

__out

HANDLE

WINAPI

CreateThread(

__in_optLPSECURITY_ATTRIBUTESlpThreadAttribute,

__inSIZE_TdwStackSize,

__inLPTHREAD_START_ROUTINElpStartAddre,

__in_optLPVOIDlpParameter,

__inDWORDdwCreationFlag,

__out_optLPDWORDlpThreadId

);

lpThreadAttribute是线程的属性。

dwStackSize是线程的栈大小。

lpStartAddre是线程函数的开始地址。

lpParameter是传送给线程函数的参数。

dwCreationFlag是创建线程标志,比如挂起线程。

lpThreadId是标识这个线程的ID。

调用这个函数的例子如下:

#001//

#002//线程运行函数。

#003//蔡军生2007/09/21

#004//

#005taticDWORDWINAPIThreadProc(

#006LPVOIDlpParameter

#007)

#008{

#009//输出到调试窗口。

#010OutputDebugString(_T("ThreadProc线程函数运行\r\n"));

#011

#012//线程返回码。

#013return0;

#014}

#015

#016

#017

#018//

#019//响应命令.

#021//

#024//菜单选项命令响应:

#025witch(nID)

#026{

#027caeIDC_CREATEBTN:

#028//显示一个按钮。

#029if(!

m_hBtn)

#030{

#031m_hBtn=CreateWindow(_T("BUTTON"),_T("按钮"),#032WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,#03350,50,100,32,

#034m_hWnd,(HMENU)IDC_BTN,m_hIntance,NULL);#035}

#036break;

#037caeIDC_BTN:

#038{

#039//传给线程的简单参数。

#040intnParam=110;

#041

#042//保存线程的ID。

#043DWORDdwThreadID=0;

#044

#045//创建线程。

#046HANDLEhThread=CreateThread(

#047NULL,//安全属性使用缺省。

#0480,//线程的堆栈大小。

#049ThreadProc,//线程运行函数地址。

#050&nParam,//传给线程函数的参数。

#0510,//创建标志。

#052&dwThreadID);//成功创建后的线程标识码。

#053

#054//等待线程结束。

#055WaitForSingleObject(hThread,INFINITE);

#056

#057//删除的线程资源。

#058CloeHandle(hThread);

#059

#060//

#061OutputDebugString(_T("按钮按下\r\n"));

#062

#063}

#064break;

#065default:

#068

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2