C++线程同步
来源:互联网 发布:表格如何筛选重复数据 编辑:程序博客网 时间:2024/05/18 17:25
线程的同步分 <用户模式的线程同步>和<内核对象的线程同步>两类
用户模式中线程的同步方法主要有原子访问和临界区等方法。特点是同步速度特别快,适合于对线程运行速度有严格要求的场合。
内核对象的线程同步则主要由事件、等待定时器、信号量以及信号灯等内核对象构成。由于这种同步机制使用了内核对象,使用时必须将线程从用户模式切换到内核模式,因此同步速度较慢,但在适用性上却要远优于用户模式的线程同步方式。
事件对象在线程退出时不会自动释放锁
互斥对象在线程退出时会自动释放锁
临界区_MFC:
事件对象:
事件对象_MFC:
用户模式中线程的同步方法主要有原子访问和临界区等方法。特点是同步速度特别快,适合于对线程运行速度有严格要求的场合。
内核对象的线程同步则主要由事件、等待定时器、信号量以及信号灯等内核对象构成。由于这种同步机制使用了内核对象,使用时必须将线程从用户模式切换到内核模式,因此同步速度较慢,但在适用性上却要远优于用户模式的线程同步方式。
事件对象在线程退出时不会自动释放锁
互斥对象在线程退出时会自动释放锁
信号量暂不讨论
互斥对象:
// ThreadTest.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "ThreadTest.h"#include <afxmt.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCWinApp theApp;using namespace std;// 互斥对象 HANDLE hMutex = NULL;// 共享资源 char g_cArray[10] = {0};UINT ThreadProc1(LPVOID lParamter){while (true){// 等待互斥对象通知WaitForSingleObject(hMutex, INFINITE);// 对共享资源进行写入操作printf("thread1 is running\n");//break; 如果线程意外中止,系统会自动释放互斥对象// 释放互斥对象ReleaseMutex(hMutex);Sleep(1000);}printf("thread1 exit\n");return 0;}UINT ThreadProc2(LPVOID lParamter){while (true){// 等待互斥对象通知WaitForSingleObject(hMutex, INFINITE);// 对共享资源进行写入操作printf("thread2 is running\n");// 释放互斥对象ReleaseMutex(hMutex);Sleep(1000);}printf("thread2 exit\n");return 0;}int MyEntry(){hMutex = CreateMutex(NULL, FALSE, NULL);// 启动线程AfxBeginThread(ThreadProc1, NULL);AfxBeginThread(ThreadProc2, NULL);// 等待计算完毕Sleep(INFINITE);return 0;}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){int nRetCode = 0;if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){cerr << _T("Fatal Error: MFC initialization failed") << endl;nRetCode = 1;}else{return MyEntry();}return nRetCode;}
互斥对象_MFC:
// ThreadTest.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "ThreadTest.h"#include <afxmt.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCWinApp theApp;using namespace std;// MFC互斥类对象 CMutex g_clsMutex(FALSE, NULL);// 共享资源 char g_cArray[10] = {0};UINT ThreadProc1(LPVOID lParamter){while (true){// 等待互斥对象通知g_clsMutex.Lock();// 对共享资源进行写入操作printf("thread1 is running\n");//break; 如果线程意外中止,系统会自动释放互斥对象// 释放互斥对象g_clsMutex.Unlock();Sleep(1000);}printf("thread1 exit\n");return 0;}UINT ThreadProc2(LPVOID lParamter){while (true){// 等待互斥对象通知g_clsMutex.Lock();// 对共享资源进行写入操作printf("thread2 is running\n");//如果线程意外中止,系统会自动释放互斥对象//break; // 释放互斥对象g_clsMutex.Unlock();Sleep(1000);}printf("thread2 exit\n");return 0;}int MyEntry(){// 启动线程AfxBeginThread(ThreadProc1, NULL);AfxBeginThread(ThreadProc2, NULL);// 等待计算完毕Sleep(INFINITE);return 0;}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){int nRetCode = 0;if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){cerr << _T("Fatal Error: MFC initialization failed") << endl;nRetCode = 1;}else{return MyEntry();}return nRetCode;}
// ThreadTest.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "ThreadTest.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCWinApp theApp;using namespace std;// 虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。// 临界区结构对象 CRITICAL_SECTION g_cs;// 共享资源 char g_cArray[10];DWORD WINAPI ThreadProc1(LPVOID lParamter){// 可以通过添加结构化异常处理代码来确保LeaveCriticalSection()语句的执行// 进入临界区EnterCriticalSection(&g_cs);// 对共享资源进行写入操作for (int i = 0; i < 10; i++){g_cArray[i] = 'a';Sleep(1);}// 离开临界区LeaveCriticalSection(&g_cs);return 0;}DWORD WINAPI ThreadProc2(LPVOID lParamter){// 进入临界区EnterCriticalSection(&g_cs);// 对共享资源进行写入操作for (int i = 0; i < 10; i++){g_cArray[10 - i - 1] = 'b';Sleep(100);}// 离开临界区LeaveCriticalSection(&g_cs);return 0;}int MyEntry(){// 必须初始化临界区InitializeCriticalSection(&g_cs);// 启动线程HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);HANDLE hThread2 = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);::CloseHandle(hThread1);::CloseHandle(hThread2);// 等待计算完毕Sleep(1000);// 结果::MessageBox(NULL, g_cArray, _T("共享资源结果:"), MB_ICONINFORMATION);return 0;}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){int nRetCode = 0;if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){cerr << _T("Fatal Error: MFC initialization failed") << endl;nRetCode = 1;}else{return MyEntry();}return nRetCode;}
临界区_MFC:
// ThreadTest.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "ThreadTest.h"#include <afxmt.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCWinApp theApp;using namespace std;// MFC临界区结构对象 CCriticalSection g_clsCriticalSection;// 共享资源 char g_cArray[10];UINT ThreadProc1(LPVOID lParamter){// 进入临界区g_clsCriticalSection.Lock();// 对共享资源进行写入操作for (int i = 0; i < 10; i++){g_cArray[i] = 'a';Sleep(10);}// 离开临界区g_clsCriticalSection.Unlock();return 0;}UINT ThreadProc2(LPVOID lParamter){// 进入临界区g_clsCriticalSection.Lock();// 对共享资源进行写入操作for (int i = 0; i < 10; i++){g_cArray[10 - i - 1] = 'b';Sleep(150);}// 离开临界区g_clsCriticalSection.Unlock();return 0;}int MyEntry(){// 启动线程AfxBeginThread(ThreadProc1, NULL);AfxBeginThread(ThreadProc2, NULL);// 等待计算完毕Sleep(1000);// 报告计算结果CString sResult(g_cArray);AfxMessageBox(sResult);return 0;}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){int nRetCode = 0;if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){cerr << _T("Fatal Error: MFC initialization failed") << endl;nRetCode = 1;}else{return MyEntry();}return nRetCode;}
事件对象:
// ThreadTest.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "ThreadTest.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCWinApp theApp;using namespace std;// 事件句柄 HANDLE hEvent = NULL;// 共享资源 char g_cArray[10];UINT ThreadProc1(LPVOID lParamter){while (true){// 等待事件置位WaitForSingleObject(hEvent, INFINITE);// 对共享资源进行写入操作printf("thread1 is running\n");// 处理完成后即将事件对象置位SetEvent(hEvent);Sleep(2000);}printf("thread1 exit\n");return 0;}UINT ThreadProc2(LPVOID lParamter){while (true){// 等待事件置位WaitForSingleObject(hEvent, INFINITE);// 对共享资源进行写入操作printf("thread2 is running\n");// 处理完成后即将事件对象置位SetEvent(hEvent);Sleep(1000);}return 0;}int MyEntry(){/*HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性BOOL bManualReset, // 复位方式.BOOL bInitialState, // 初始状态.为TRUE时,其它线程可获取hEvent,否则要等待到有信号时LPCTSTR lpName // 对象名称);*/// 创建事件hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);// 事件置位//SetEvent(hEvent);// 启动线程AfxBeginThread(ThreadProc1, NULL);AfxBeginThread(ThreadProc2, NULL);// 等待计算完毕Sleep(INFINITE);CloseHandle(hEvent);return 0;}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){int nRetCode = 0;if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){cerr << _T("Fatal Error: MFC initialization failed") << endl;nRetCode = 1;}else{return MyEntry();}return nRetCode;}
事件对象_MFC:
// ThreadTest.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "ThreadTest.h"#include <afxmt.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCWinApp theApp;using namespace std;// MFC事件类对象CEvent g_clsEvent(FALSE, FALSE, NULL, NULL);// 共享资源 char g_cArray[10] = {0};UINT ThreadProc1(LPVOID lParamter){while (true){// 等待锁,直到得到锁g_clsEvent.Lock();// 对共享资源进行写入操作printf("thread1 is running\n");// 处理完成后即将事件对象置位g_clsEvent.SetEvent();Sleep(1000);}printf("thread1 exit\n");return 0;}UINT ThreadProc2(LPVOID lParamter){while (true){// 等待锁,直到得到锁g_clsEvent.Lock();// 对共享资源进行写入操作printf("thread2 is running\n");// 处理完成后即将事件对象置位g_clsEvent.SetEvent();Sleep(1000);}g_clsEvent.Unlock();printf("thread2 exit\n");return 0;}int MyEntry(){// 事件置位SetEvent(g_clsEvent);// 启动线程AfxBeginThread(ThreadProc1, NULL);AfxBeginThread(ThreadProc2, NULL);// 等待计算完毕Sleep(INFINITE);return 0;}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){int nRetCode = 0;if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){cerr << _T("Fatal Error: MFC initialization failed") << endl;nRetCode = 1;}else{return MyEntry();}return nRetCode;}
- C#lock线程同步
- C# 线程同步问题
- Linux C线程同步
- C/C++线程同步
- linux c 线程同步
- C++【线程同步】-临界区同步
- Linux C 线程同步实例
- c/c++线程--2线程同步
- Linux C 信号、线程同步、线程互斥锁、线程条件变量
- C #中的几个线程同步对象方法
- C #中的几个线程同步对象方法
- 《windows via C++》之windows线程同步
- 《windows via C++》之windows线程同步
- Visual C 线程同步技术剖析
- C #中的几个线程同步对象方法
- C #中的几个线程同步对象
- 《windows via C++》之windows线程同步
- C #中的几个线程同步对象方法
- GIT基本概念和用法总结
- 知乎要“膨胀”了
- Java内存管理
- ubuntu下的截屏软件scrot的安装与使用
- 8 个实用的 Linux netcat 命令示例
- C++线程同步
- 印前图文输出检查要点
- eclipse 快捷键
- Java泛型中通配符的几点理解
- Yii基础百问:yii的多语言怎么用?怎么配置?--第2问
- Python Exercise #1
- zoj_1586 QS Network
- ZRB老师上课讲的一些开发技巧
- 如何拼好八开胶印商标版