}
returnnRetCode;
}
voidThreaName1()
{printf("ThreadisRunning!
!
\n");
}
【注意】:
文件的路径一定是能够匹配的。
【基础知识】:
(1)lpThreadAttributes:
为线程指定安全属性.为NULL时,线程得到一个默认的安全描述符.
(2)dwStackSize:
线程堆栈的大小.其值为0时,其大小与调用该线程的线程堆栈大小相同.
(3)lpStartAddress:
指定线程要执行的函数.
(4)lpparameter:
函数中要传递的参数.
(5)dwCreationFlags:
指定线程创建后所处的状态.若为CRRATE_SUSPENDED,表示创建后出
于挂起状态,用ResumeThread()激活线程才可以执行.若该值为0,表示线程创建后立即执行.
(6)lpThreadId:
用一个32位的变量接受系统返回的线程标识符.若该值设为NULL,系统不
返回线程标识符.
2.2线程的同步
//Semaphore.cpp:
Definestheentrypointfortheconsoleapplication.
#include"stdafx.h"
#include"Semaphore.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
//Theoneandonlyapplicationobject
CWinApptheApp;
usingnamespacestd;
staticHANDLEh1;//线程句柄
staticHANDLEhHandle1=NULL;//信号量句柄
voidfunc();
int_tmain(intargc,TCHAR*argv[],TCHAR*envp[])
{
intnRetCode=0;
DWORDdwThreadID1;
DWORDdRes,err;
hHandle1=CreateSemaphore(NULL,0,1,"SemaphoreName1");//创建一个信号量
if(hHandle1==NULL)printf("SemaphoreCreate!
\n");
elseprintf("SemaphoreCreateSuccess!
\n");
hHandle1=OpenSemaphore(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE,
NULL,
"SemaphoreName1");//打开信号量
if(hHandle1==NULL)printf("SemaphoreOpenFail!
\n");
elseprintf("SemaphoreOpenSuccess!
\n");
h1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func,
(LPVOID)NULL,
0,&dwThreadID1);//创建子进程
if(h1==NULL)printf("Thread1createFail!
\n");
elseprintf("Thread1createSuccess!
\n");
dRes=WaitForSingleObject(hHandle1,INFINITE);//主线程等待子线程结束
err=GetLastError();
printf("WaitForSingleObjecterr=%d\n",err);
if(dRes==WAIT_TIMEOUT)printf("TIMEOUT!
dRes=%d\n",dRes);
elseif(dRes==WAIT_OBJECT_0)printf("WAIT_OBJECT!
dRes=%d\n",dRes);
elseif(dRes==WAIT_ABANDONED)
printf("WAIT_ABANDONED!
Dres=%d\n",dRes);
elseprintf("dRes=%d\n",dRes);
CloseHandle(h1);
CloseHandle(hHandle1);
ExitThread(0);
returnnRetCode;
}
voidfunc()
{
BOOLrc;
DWORDerr;
printf("NowInThread!
\n");
rc=ReleaseSemaphore(hHandle1,1,NULL);
err=GetLastError();
printf("ReleaseSemaphoreerr=%d\n",err);
if(rc==0)printf("SemaphoreReleaseFail!
\n");
elseprintf("SemaphoreReleaseSuccess!
rc=%d\n",rc);
}
运行情况:
【基础知识】:
等待对象(waitfuctions)函数包括等待一个对象(WaitForSingleObject())和等待多对
象(WaitForMultipleObject())两个API函数。
等待一个对象
WaitForMultipleObject()用于等待一个对象。
他等待的对象可以为以下对象之一。
Changenotification:
变化通知。
Consoleinput:
控制台输入。
Events:
事件。
Job:
作业。
Mutex:
互斥信号量。
Process:
进程。
Semaphore:
计数信号量。
Thread:
线程。
Waitabletimer:
定时器。
原型:
DWORDWaitForSingleObject(
HANDLEhHandle,//对象句柄
DWORDdwMilliseconds//等待时间
);
参数说明:
hHandle:
等待对象的对象句柄。
该对象句柄必须为SYNCHRONIZE访问。
dwMilliseconds:
等待时间,单位为ms。
若改值为0,函数在测试对象的状态后立即返
回,若为INFINITE,函数一直等待下去,直到收到一个信号将其唤醒,如表2‐1所示。
返回值:
如果返回成功,其返回值说明是何种事件导致函数返回。
表2‐1函数描述
访问描述
WAIT_ABANDONED等待对象的是一个互斥(mutex)对象,该互斥对象没有被拥
有它的线程释放,他被设置为不能被唤醒
WAIT_OBJECT_0指定对象被唤醒
WAIT_TIMEOUT超时
用法举例:
StaiticHANDLEhHandle1=NULL;
DWORDdRes;
dRes=WaitForSingleObject(hHandle1,10);//等待对象的句柄为hHandle,等待时间为
1000ms
等待多个对象
WaitForMultipleObject()在指定时间内等待多个对象,他等待的对象与
WaitForSingleObject()相同。
原型:
DWORDWaitForMultipleObject(
DWORDnCount,//句柄数组中的句柄数
XONSTHANDLE*lpHandles,//指向对象句柄数组的指针
BOOLfWaitAll,//等待类型
DWORDdwMilliseconds//等待时间
);
参数说明:
nCount:
由指针*lpHandles指定的句柄数组中的句柄数,最大数是
MAXIMUM_WAIT_OBJECTS。
*lpHandles:
指向对象句柄数组的指针。
fWAitAll:
等待类型。
若存为true,当由lpHandles数组指定的所有对象被唤醒时函数返
回;若为FALSE,当由lpHandles数组制定的某一个对象被唤醒时函数返回,且有返回值说
明事由哪个对象引起的函数返回。
dwMilliseconds:
等待时间。
单位为ms。
若该值为0,函数测试对象的状态后立即返回;
若为INFINITE,函数一直等待下去,直到收到一个信号将其唤醒。
返回值:
如果成功返回,其返回值说明是何种事件导致函数返回。
各参数的描述如表2‐2所示。
表2‐2各参数描述
访问描述
WAIT_OBJECT_0to(WAIT_OBJECT若bWaitAll为TRUE,返回值说明所有被等待的对象均
被唤醒;若
_0+nCount‐1)bWaitAll为FALSE。
返回值减去WAIT_OBJECT_0说明
lpHandles数组下标指定的对象满足等待条件。
如果调用时多个对象同时被唤醒,则取多个
对象中最小的那个数组下标
WAIT_ABANDONED_0to若bWaitAll为TRUE,返回值说明所有被等带的对象
均被唤醒,并且(WIAT_ABANDONED‐0+NcOUNT‐1)至少有一个对象是没有约束的互斥
对象;若bWaitAll
为FALSE,返回值减去WAIT_ABANDONED_0说明lpHandles数组下标指定的没有约束的互斥
对象满足等待条件
WAIT_TIMNEOUT超时且参数bWaitAll指定的条件不能满足
信号量对象(semaphore)
信号量对象(semaphore)包括创建信号量(CreateSemaphore())打开信号量
OpenSemaphore()及增加信号量的值(ReleaseSemaphore())API函数。
创建信号量
CreateSemaphore()用于创建一个信号量。
原型:
HANDLECreateSemaphore(
LPSECURITY_ATTRIBUTESlpSemaphoreAttributes,//安全属性
LONGlInitialCount,//信号量对象初始值
LONGliMaximumCount,//信号量最大值
LPCTSTRlpName//信号量名
);
参数说明:
lpSemaphoreAttributes:
指定安全属性,为null是,信号量得到一个默认的安全描述符。
lInitialCount:
指定信号量对象的初始值。
该值必须大于等于0,小于等于
lMaximumCount。
当其值大于0是,信号量被唤醒。
当该函数释放了一个等待该信号量的
线程时,lInitialCount值减1,当调用函数ReleaseSemaphore()时,按其指定的数量加一个值。
lMaximumCount:
指出该信号量的最大值,该值必须大于0.
lpName:
给出该信号量的名字。
返回值:
信号量创建成功,将返回该型号量的句柄。
如果给出的信号量名是系统已经存在的信号
量,将返回这个已经存在的信号量的句柄。
如果失败,系统返回null,还可以调用函数
GEtLastError()查询失败的原因。
用法举例:
StaticHANDLEhHandle1=null;
//创建一个信号量,其初值为0,最大值为5,信号量的名字为“SemphoreName1”
hHnadle1=CreateSemaphore(NULL,0,5,"SemphoreName1");
打开信号量
OpenSemaphore()用于打开一个信号量。
原型:
HANDLEOpenSemaphore(
DWORDdwDesidedAccess,//访问标志
BOOLbInheritHandle,//继承标志
LPCTSTRlpNme//信号量名
);
参数说明:
(1).dwDesiredAccess:
指出打开后要对信号量进行何种访问,如表2-3所示。
表2‐3访问状态
访问描述
SEMAPHORE_ALL_ACCESS可以进行任何对信号量的访问
SEMPHORE_MODFIY_STATE可以使用ReleaseSemaphore()修改信号量的值,使信号量
的值成为可用状态
SYNCHRONIZE使用等待函数(waitfunctions),等待信号量成为可用状态
(2).bInheritHandle:
指出返回的的信号量句柄是否可以继承。
(3).lpName:
给出信号量的名字
返回值:
信号量打开成功,将返回信号量的句柄;如果失败,系统返回null,可以调用函数
GetLastError()查询失败的原因。
;
用法举例:
StaticHANDLEhHandle1=null;
//打开一个名为”SemphoreName1”的信号量,之后可使用ReleaseSemaphore()函
数增加信号量的值hHandle1=OpenSemaphore(SEMAPHORE_MOFDIFY_START,NULL,”
SemphoreName1”);
3.增加信号量的值
ReleaseSemaphore()用于增加信号量的值。
原型:
BOOLReleaseSemaphore(
HANDLEhSemaphore,//信号量对象句柄
LONGlReleaseCount,//信号量要增加数值
LPLONGlpPreiousCount//信号量要增加数值地址
);
参数说明:
(1).hSemaphore:
创建或打开信号量时给出的信号量对象句柄。
WindowsNT中建议
使用SEMAPHORE_MODIFY_STARTE访问属性打开该信号量。
(2).lReleaseCount:
信号量要增加数值。
该值必须大于0。
如果增加该值后大于信号
创建时给出的lMaximumCount值,则增加操作失效,函数返回FALSE。
(3).lpPreiousCount:
接收信号量的一个32位的一个变量。
若不需要接受该值,可
以指定为null。
返回值:
如果成功,将返回一个非0值;如果失败,系统返回一个0,可以调用一个GetLastError
()查询失败的原因。
用法举例:
StaticHANDLEhHandle1=NULL;
BOOLrc;
rc=ReleaseSemaphore(hHandle1,1,NULL);//给信号量的值加1;