C++实现多线程及其三种方法实现多线程同步
1.调用windows API实现多线程
#include "stdafx.h" #include <windows.h> #include <stdio.h> #include <iostream> DWORD WINAPI myfun1(LPVOID lpParameter); //声明线程函数 DWORD WINAPI myfun2(LPVOID lpParameter); using namespace std; int _tmain(int argc, _TCHAR* argv[]) { HANDLE h1,h2;//声明句柄变量 h1=CreateThread(NULL,0,myfun1,NULL,0,NULL);//创建线程1 cout<<"线程1开始运行! "<<endl; h2=CreateThread(NULL,0,myfun2,NULL,0,NULL);//创建线程2 cout<<"线程2开始运行!"<<endl; //关闭线程句柄对象 CloseHandle(h1); CloseHandle(h2); int n=0; while (1) { //cout<<"测试是不是循环重复执行"<<n++<<endl; if (getchar()=="q")//如果用户输入字符q { return 0;//程序正常退出 } else { Sleep(100);//程序睡眠 } } } //分别实现线程函数,并返回值 DWORD WINAPI myfun1(LPVOID lpParameter) { cout<<"线程1正在运行"<<endl; return 0; } DWORD WINAPI myfun2(LPVOID lpParameter) { cout<<"线程2正在运行"<<endl; return 0; }
2.使用临界区对象、事件对象和互斥对象三种方法实现多线程同步
#include "stdafx.h" #include <windows.h> #include <iostream> using namespace std; DWORD WINAPI myfun1(LPVOID lpParameter); //声明线程函数 DWORD WINAPI myfun2(LPVOID lpParameter); /************使用临界区对象实现多线程同步*************** 临界区被初始化后,当程序进入临界区后便拥有临界区的所有权,其余线程无权进入只能等对方释放临界区之后,方可进入临界区拥有其所有权再对临界区进行操作 InitializeCriticalSection()初始化临界区; EnterCriticalSection()进入临界区; LeaveCriticalSection()释放临界区所有权并离开临界区; 注意:上述是windows API中相关函数,CCriticalSection类是MFC中定义的临界区类,需要在MFC程序中使用(此程序为控制台程序无法使用MFC类),可以操作临界区,lock锁定临界区、unlock释放临界区 临界区为依次访问,不能实现其中一个线程一释放临界区就会被另一个线程访问临界区!不能实现实时监听 ********************************************************/ /************使用事件对象实现多线程同步*************** 事件对象是指用户在程序中使用内核对象的有无信号状态实现线程的同步临界区被初始化后,当程序进入临界区后便拥有临界区的所有权,其余线程无权进入只能等对方释放临界区之后,方可进入临界区拥有其所有权再对临界区进行操作 CreatEvent()创建并返回事件对象; SetEvent()将指定的事件设置为有信号状态(有信号状态下其余线程可以访问); ResetEvent()将指定的事件设置为无信号状态; 除SetEvent函数外,WaitForSingleObject函数等待指定事件。 注意:上述是Windows API函数,CEvent类是MFC实现事件对象的类 事件对象为立即访问,一旦事件对象被设置为有信号 立刻会被其余线程访问!能实现实时监听 ********************************************************/ /************使用互斥对象实现多线程同步*************** 互斥对象还可以在进程间使用,在实现线程同步时包含一个线程ID和一个计数器,线程ID表示拥有互斥对象的线程,计数器表示该互斥对象被同一线程所使用次数 CreatMutex()创建并返回互斥对象; ReleaseMutex()释放互斥对象句柄; WaitForSingleObject()对该对象进行请求。 注意:上述是Windows API函数,CMutex类是MFC中的互斥对象类 互斥对象为立即访问,一旦互斥对象被释放 立刻会被其它正在等待的线程访问!能实现实时监听 ********************************************************/ static int a=0; CRITICAL_SECTION section;//定义临界区对象(Windows API) HANDLE hevent;//定义全局事件变量句柄 HANDLE hmutex;//定义全局互斥对象句柄 int _tmain(int argc, _TCHAR* argv[]) { HANDLE h1,h2;//声明句柄变量 //InitializeCriticalSection(§ion);//初始化临界区对象(需要在线程前初始化) //hevent=CreateEvent(NULL,FALSE,false,NULL);//创建事件并返回句柄 //SetEvent(hevent);//设置事件为有信号状态 hmutex=CreateMutex(NULL,false,NULL);//创建互斥对象并返回其句柄 h1=CreateThread(NULL,0,myfun1,NULL,0,NULL);//创建线程1 cout<<"线程1开始运行! "<<endl; h2=CreateThread(NULL,0,myfun2,NULL,0,NULL);//创建线程2 cout<<"线程2开始运行!"<<endl; //关闭线程句柄对象 CloseHandle(h1); CloseHandle(h2); while (1) { if (getchar()=="q")//如果用户输入字符q { //DeleteCriticalSection(§ion);//删除临界区对象 return 0;//程序正常退出 } else { Sleep(100);//程序睡眠 } } return 0; } //分别实现线程函数,并返回值 DWORD WINAPI myfun1(LPVOID lpParameter) { while (true) { //EnterCriticalSection(§ion);//进入临界区 //WaitForSingleObject(hevent,INFINITE);//请求事件对象 //ResetEvent(hevent);//设置事件对象为无信号状态 WaitForSingleObject(hmutex,INFINITE);//请求互斥对象 a++; if (a<1000) { cout<<"线程1正在计数"<<a<<endl; //LeaveCriticalSection(§ion);//离开临界区 //SetEvent(hevent); ReleaseMutex(hmutex);//释放互斥对象句柄 } else { //a=0; //LeaveCriticalSection(§ion); //SetEvent(hevent); ReleaseMutex(hmutex);//释放互斥对象句柄 break; } } return 0; } DWORD WINAPI myfun2(LPVOID lpParameter) { // a=0; while (true) { //EnterCriticalSection(§ion);//进入临界区 //WaitForSingleObject(hevent,INFINITE);//请求事件对象 //ResetEvent(hevent);//设置事件对象为无信号状态 WaitForSingleObject(hmutex,INFINITE);//请求互斥对象 a++; if (a<1000) { cout<<"线程2正在计数"<<a<<endl; //LeaveCriticalSection(§ion);//离开临界区 //SetEvent(hevent); ReleaseMutex(hmutex);//释放互斥对象句柄 } else { //LeaveCriticalSection(§ion);//离开临界区,当计数a大于1000时退出循环 //SetEvent(hevent); ReleaseMutex(hmutex);//释放互斥对象句柄 break; } } return 0; }
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇:没有了