您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 能源与动力工程 > windows多线程编程
一:利用事件实现线程同步1.createthread函数的用法hThread=CreateThread(&security_attributes,dwStackSize,ThreadProc,pParam,dwFlags,&idThread);HANDLECreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,DWORDdwStackSize,LPTHREAD_START_ROUTINElpStartAddress,LPVOIDlpParameter,DWORDdwCreationFlags,LPDWORDlpThreadId);第一个参数是指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows98中忽略该参数。在WindowsNT中,它被设为NULL。第二个参数是用于新线程的初始堆栈大小,默认值为0。在任何情况下,Windows根据需要动态延长堆栈的大小。第三个参数是指向线程函数的指标。函数名称没有限制,但是必须以下列形式声明:DWORDWINAPIThreadProc(LPVOIDpParam);第四个参数为传递给ThreadProc的参数。这样主线程和从属线程就可以共享数据,这个参数既可以是数值,也可以是指向其他信息的指针。第五个参数通常为0,表示创建之后立刻运行,但当建立的线程不马上执行时为可设置为CREATE_SUSPENDED。线程将暂停直到呼叫ResumeThread来恢复线程的执行为止。第六个参数时一个返回值,它用来接收线程的ID,可以为该参数传递NULL,表明我们对该线程的ID不感兴趣。函数返回值为新线程的句柄。2.CreateEvent函数HANDLECreateEvent(LPSECURITY_ATTRIBUTESlpEventAttributes,//安全属性BOOLbManualReset,//复位方式BOOLbInitialState,//初始状态LPCTSTRlpName//对象名称);lpEventAttributes[输入]一个指向SECURITY_ATTRIBUTES结构的指针,确定返回的句柄是否可被子进程继承。如果lpEventAttributes是NULL,此句柄不能被继承。WindowsNT/2000:lpEventAttributes的结构中的成员为新的事件指定了一个安全符。如果lpEventAttributes是NULL,事件将获得一个默认的安全符。bManualReset[输入]指定将事件对象创建成手动复原还是自动复原。如果是TRUE,那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。如果设置为FALSE,当一个等待线程被释放以后,系统将会自动将事件状态复原为无信号状态。bInitialState[输入]指定事件对象的初始状态。如果为TRUE,初始状态为有信号状态;否则为无信号状态。lpName[输入]指定事件的对象的名称,是一个以0结束的字符串指针。名称的字符格式限定在MAX_PATH之内。名字是对大小写敏感的。如果lpName指定的名字,与一个存在的命名的事件对象的名称相同,函数将请求EVENT_ALL_ACCESS来访问存在的对象。这时候,由于bManualReset和bInitialState参数已经在创建事件的进程中设置,这两个参数将被忽略。如果lpEventAttributes是参数不是NULL,它将确定此句柄是否可以被继承,但是其安全描述符成员将被忽略。如果lpName为NULL,将创建一个无名的事件对象。如果lpName的和一个存在的信号、互斥、等待计时器、作业或者是文件映射对象名称相同,函数将会失败,在GetLastError函数中将返回ERROR_INVALID_HANDLE。造成这种现象的原因是这些对象共享同一个命名空间。终端服务(TerminalServices):名称中可以加入Global\或是Local\的前缀,这样可以明确的将对象创建在全局的或事务的命名空间。名称的其它部分除了反斜杠(\),可以使用任意字符。详细内容可参考KernelObjectNameSpaces。Windows2000:在Windows2000系统中,没有终端服务运行,Global\和Local\前缀将被忽略。名称的其它部分除了反斜杠(\),可以使用任意字符。WindowsNT4.0以及早期版本,Windows95/98:名称中除了反斜杠(\),可以使用任意字符。//MultiThread.cpp:定义控制台应用程序的入口点。代码一:线程不同步的例子(基于事件)#includestdafx.h#includestdio.h#includewindows.hDWORDWINAPIFun1Proc(LPVOIDlpParameter);DWORDWINAPIFun2Proc(LPVOIDlpParameter);HANDLEg_hEvent;inttiket=100;int_tmain(intargc,_TCHAR*argv[]){HANDLEThread1;HANDLEThread2;g_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);Thread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);Thread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(Thread1);CloseHandle(Thread2);SetEvent(g_hEvent);//Sleep(10);system(pause);return0;}DWORDWINAPIFun1Proc(LPVOIDlpParameter){while(1){//Sleep(1);if(tiket0){WaitForSingleObject(g_hEvent,INFINITE);printf(Thread1selltiket%d\n,tiket);tiket--;SetEvent(g_hEvent);}else{//SetEvent(g_hEvent);break;}}return0;}DWORDWINAPIFun2Proc(LPVOIDlpParameter){while(1){//Sleep(1);WaitForSingleObject(g_hEvent,INFINITE);if(tiket0){printf(Thread2selltiket%d\n,tiket);tiket--;SetEvent(g_hEvent);}else{//SetEvent(g_hEvent);break;}}return0;}代码二:线程同步的例子(基于事件)#includestdafx.h#includestdio.h#includewindows.hDWORDWINAPIFun1Proc(LPVOIDlpParameter);DWORDWINAPIFun2Proc(LPVOIDlpParameter);HANDLEg_hEvent;inttiket=100;int_tmain(intargc,_TCHAR*argv[]){HANDLEThread1;HANDLEThread2;g_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);Thread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);Thread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(Thread1);CloseHandle(Thread2);SetEvent(g_hEvent);//Sleep(10);system(pause);return0;}DWORDWINAPIFun1Proc(LPVOIDlpParameter){while(1){//Sleep(1);WaitForSingleObject(g_hEvent,INFINITE);if(tiket0){printf(Thread1selltiket%d\n,tiket);tiket--;SetEvent(g_hEvent);}else{//SetEvent(g_hEvent);break;}}return0;}DWORDWINAPIFun2Proc(LPVOIDlpParameter){while(1){//Sleep(1);WaitForSingleObject(g_hEvent,INFINITE);if(tiket0){printf(Thread2selltiket%d\n,tiket);tiket--;SetEvent(g_hEvent);}else{//SetEvent(g_hEvent);break;}}return0;}二:利用互斥对象实现线程同步CreateMutex()函数可用来创建一个有名或无名的互斥量对象,该对象是一个内核对象,它能够确保线程对单个资源的互斥访问权。其函数原型为:HANDLECreateMutex(LPSECURITY_ATTRIBUTESlpMutexAttributes,//指向安全属性的指针BOOLbInitialOwner,//初始化互斥对象的所有者LPCTSTRlpName//指向互斥对象名的指针);返回值:如执行成功,就返回互斥体对象的句柄;零表示出错。会设置GetLastError。即使返回的是一个有效句柄,但倘若指定的名字已经存在,GetLastError也会设为ERROR_ALREADY_EXISTS。参数表:lpMutexAttributesSECURITY_ATTRIBUTES,指定一个SECURITY_ATTRIBUTES结构,可以赋值NULL,表示让互斥对象拥有默认的安全属性。bInitialOwnerLong:若为TRUE,则创建该互斥对象的线程拥有该互斥对象的所有权,否则,没有所有权。lpNameString,指定互斥体对象的名字。若为NULL,表示创建一个匿名的互斥对象。注意:如果线程对共享资源的访问结束后,应该释放互斥对象的所有权,即将互斥对象置于有信号的状态,使用函数BOOLWIANPIReleaseMutex(HANDLEhMutex);返回值:函数返回成功,返回非0,否则返回0;参数:互斥对象的句柄。对于互斥对象遵循谁拥有谁释放的原则。代码三:#includestdafx.h#includestdio.h#includewindows.hDWORDWINAPIFun1Proc(LPVOIDlpParameter);DWORDWINAPIFun2Proc(LPVOIDlpParameter);HANDLEh_Mutex;inttiket=100;int_tmain(intargc,_TCHAR*argv[]){HANDLEThread1;HANDLEThread2;h_Mutex=CreateMutex(NULL,FALSE,NULL);Thread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);Thread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(Thread1);CloseHandle(Thread2);//Sleep(10);system(pause);return0;}DWORDWINAPIFun1Proc(LPVOIDlpParameter){while(1){//Sleep(1);WaitForSingleObject(h_Mutex,INFINITE);if(tiket0){printf(Thread1selltiket%d\n,tiket);tiket--;ReleaseMutex(h_Mutex);}else{break;}}re
本文标题:windows多线程编程
链接地址:https://www.777doc.com/doc-2867639 .html