C++实现多线程及其三种方法实现多线程同步

来源:互联网 发布:淘宝虚拟对话生成器 编辑:程序博客网 时间:2024/06/06 04:32

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);//创建线程1cout<<"线程1开始运行!\n"<<endl;h2=CreateThread(NULL,0,myfun2,NULL,0,NULL);//创建线程2cout<<"线程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);//创建线程1cout<<"线程1开始运行!\n"<<endl;h2=CreateThread(NULL,0,myfun2,NULL,0,NULL);//创建线程2cout<<"线程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;}


原创粉丝点击