MFC-线程同步
2016-04-02 16:31
211 查看
线程同步有四种方法.
两个简单的线程函数例子:
方法一:使用临界区对象(CCriticalSection类)
1.在构造函数中创建一个临界区对象
2.分别给两个(或多个)线程加锁
3.在析构函数中释放临界区对象
这个同步方法相对于其它三种方法是最快的
方法二:使用互斥对象(CMutex类)
1.在构造函数中创建互斥对象
2.分别给两个(或多个)线程加锁
3.在析构函数中释放互斥对象
这个方法比方法一慢了许多
方法三:使用信号量对象(CSemaphore类)
信号量是CSemaphore的对象,该对象的作用是对访问某个共享资源的线程的数目进行控制。
CSemaphore类的构造函数原型如下:
1.在构造函数中创建信号量对象
2.分别给两个(或多个)线程加锁
3.在析构函数中释放信号量对象
方法4:使用事件对象(CEvent类)
1.在构造函数创建事件对象
2.分别给两个(或多个)线程加锁
两个简单的线程函数例子:
UINT Thread1(LPVOID lParam) { for (int i = 0; i < 10000000;i++) { sum++; } SetDlgItemInt(AfxGetApp()->m_pMainWnd->m_hWnd, IDC_STATIC,sum,TRUE); return 0; } UINT Thread2(LPVOID lParam) { for (int i = 0; i < 10000000; i++) { sum++; } SetDlgItemInt(AfxGetApp()->m_pMainWnd->m_hWnd, IDC_STATIC, sum, TRUE); return 0; }
方法一:使用临界区对象(CCriticalSection类)
1.在构造函数中创建一个临界区对象
g_critical_section = new CCriticalSection();
2.分别给两个(或多个)线程加锁
for (int i = 0; i < 10000000;i++) { //加锁 g_critical_section->Lock(); sum++; //当操作共享数据时为了防止同时被操作导致结果错误, //所以要加锁,这个时候其它线程就不能对这个加锁的数据进程操作,需要等到这个数据解锁才能进程操作 //解锁 g_critical_section->Unlock(); }
3.在析构函数中释放临界区对象
delete g_critical_section; g_critical_section = nullptr;
这个同步方法相对于其它三种方法是最快的
方法二:使用互斥对象(CMutex类)
1.在构造函数中创建互斥对象
g_mutex = new CMutex();
2.分别给两个(或多个)线程加锁
//利用互斥对象作为参数,创建一个信号锁 CSingleLock singlelock(g_mutex); for (int i = 0; i < 1000000; i++) { //加锁 singlelock.Lock(); //可能加锁失败,要判断是否加锁成功 if (singlelock.IsLocked()) { sum++; //当操作共享数据时为了防止同时被操作导致结果错误, //所以要加锁,这个时候其它线程就不能对这个加锁的数据进程操作,需要等到这个数据解锁才能进程操作 //解锁 singlelock.Unlock(); } }
3.在析构函数中释放互斥对象
delete g_mutex; g_mutex = nullptr;
这个方法比方法一慢了许多
方法三:使用信号量对象(CSemaphore类)
信号量是CSemaphore的对象,该对象的作用是对访问某个共享资源的线程的数目进行控制。
CSemaphore类的构造函数原型如下:
CSemaphore( LONG lInitialCount /* = 1 */, //计数器的初始值 LONG lMaxCount /* = 1 */, //计数器的最大计数值 LPCTSTR pstrName/* =NULL */, //信号的名称 LPSECURITY_ATTRIBUTES lpsaAttributes /* = NULL */ //指向一个SECURITY_ATTRIBUTES结构的指针 )
1.在构造函数中创建信号量对象
//因为这个例子只有2个线程,所以计数器只要一个就行 g_semaphore = new CSemaphore(1,1);
2.分别给两个(或多个)线程加锁
//利用信号量对象作为参数,创建一个信号锁 CSingleLock singlelock(g_semaphore); for (int i = 0; i < 1000000; i++) { //加锁 singlelock.Lock(); //可能加锁失败,要判断是否加锁成功 if (singlelock.IsLocked()) { sum++; //当操作共享数据时为了防止同时被操作导致结果错误, //所以要加锁,这个时候其它线程就不能对这个加锁的数据进程操作,需要等到这个数据解锁才能进程操作 //解锁 singlelock.Unlock(); } }
3.在析构函数中释放信号量对象
delete g_semaphore; g_semaphore = nullptr;
方法4:使用事件对象(CEvent类)
1.在构造函数创建事件对象
g_event = new CEvent(TRUE);
2.分别给两个(或多个)线程加锁
//利用事件对象作为参数,创建一个信号锁 CSingleLock singlelock(g_event); for (int i = 0; i < 1000000; i++) { //加锁 singlelock.Lock(); //可能加锁失败,要判断是否加锁成功 if (singlelock.IsLocked()) { sum++; //当操作共享数据时为了防止同时被操作导致结果错误, //所以要加锁,这个时候其它线程就不能对这个加锁的数据进程操作,需要等到这个数据解锁才能进程操作 //解锁 singlelock.Unlock(); g_event->SetEvent();//必须要告诉其它线程本线程已经解锁,你可以加锁了 } }
相关文章推荐
- pycharm5.0专业版出现的乱码问题
- c# 技巧之 泛型方法
- C++中的vector
- JS 间隔固定时间重复运行的方法
- Android开发:对图片进行简单的编辑
- 基数排序
- [Python笔记][第二章Python序列-复杂的数据结构]
- [Python笔记][第二章Python序列-复杂的数据结构]
- jQuery-Form Vaildation小项目.
- OpenCV2基础操作----直线、矩形、圆、椭圆函数的使用
- 路由器和交换的本质区别解析
- linux 的命令行输出进度条
- 【day0402】C++异常处理---错误但能处理的
- 四、Redis常用命令
- javascript的加载、解析、执行对浏览器渲染的影响
- [Python笔记][第二章Python序列-tuple,dict,set]
- linux基础相关
- [Python笔记][第二章Python序列-tuple,dict,set]
- CAD批量打印
- [python笔记][第二章Python序列-list]