Windows编程-- 用户方式中线程的同步---关键代码段(临界区)
2011-01-05 15:28
615 查看
可以从例子学习,更好的掌握
应该注意的:
1 关键代码段(临界区)工作在用 用户方式下
2 关键代码段(临界区)是指一个小代码段,在代码够执行前。它必须独占对某些资源的访问权。
3 关键代码段是工作在用户方式下。同步速度较快,但在使用关键代码段时,很容易进入死锁状态。因为在等待进入关键代码段时无法设定超时值。
4 线程死锁 线程1拥有了临界区对象A。等待临界区对象B的拥有权。线程2拥有了临界区对象B,等待临界区对象A的拥有权,就造成了死锁。
5 无法用它们对多个进程中的各个线程进行同步
以下的例子就是进入了死锁。
#include <windows.h> #include <iostream.h> //两个线程的声明 DWORD WINAPI Fun1Proc(LPVOID lpParameter); DWORD WINAPI Fun2Proc(LPVOID lpParameter); int tickets = 100; CRITICAL_SECTION g_cs; //定义一个临界区 int main() { HANDLE hThread1; HANDLE hThread2; hThread1=CreateThread(NULL,0, Fun1Proc, NULL,0, NULL); hThread2=CreateThread(NULL,0, Fun2Proc, NULL,0, NULL); CloseHandle(hThread1); CloseHandle(hThread2); InitializeCriticalSection(&g_cs); //初始化临界区 Sleep(4000); DeleteCriticalSection(&g_cs); //当临界区里没有资源时释放掉临界区(可以这样说吗)??? return 0; } DWORD WINAPI Fun1Proc(LPVOID lpParameter) { while (TRUE) { EnterCriticalSection(&g_cs); //该线程进入临界区 if (tickets > 0) { Sleep( 1); cout<< "Thread1 sell tickets:"<< tickets-- << endl; } else { break; } LeaveCriticalSection(&g_cs); //退出临界区 } return0; } DWORD WINAPI Fun2Proc(LPVOID lpParameter) { while(TRUE) { EnterCriticalSection(&g_cs); //该线程进入临界区 if(tickets > 0) { Sleep( 1); cout<< "Thread2 sell tickets:"<< tickets-- << endl; } else { break; } LeaveCriticalSection(&g_cs); //退出临界区 } return 0; }
应该注意的:
1 关键代码段(临界区)工作在用 用户方式下
2 关键代码段(临界区)是指一个小代码段,在代码够执行前。它必须独占对某些资源的访问权。
3 关键代码段是工作在用户方式下。同步速度较快,但在使用关键代码段时,很容易进入死锁状态。因为在等待进入关键代码段时无法设定超时值。
4 线程死锁 线程1拥有了临界区对象A。等待临界区对象B的拥有权。线程2拥有了临界区对象B,等待临界区对象A的拥有权,就造成了死锁。
5 无法用它们对多个进程中的各个线程进行同步
以下的例子就是进入了死锁。
#include <windows.h> #include <iostream.h> //1、两个线程的声明 DWORD WINAPI Fun1Proc(LPVOID lpParameter); DWORD WINAPI Fun2Proc(LPVOID lpParameter); int tickets = 100; CRITICAL_SECTION g_csA; //2、定义两个临界区 CRITICAL_SECTION g_csB; int main() { HANDLE hThread1; HANDLE hThread2; hThread1=CreateThread(NULL,0, Fun1Proc, NULL,0, NULL); hThread2=CreateThread(NULL,0, Fun2Proc, NULL,0, NULL); CloseHandle(hThread1); CloseHandle(hThread2); InitializeCriticalSection(&g_csA); //3、初始化临界区 InitializeCriticalSection(&g_csB); Sleep(4000); DeleteCriticalSection(&g_csA); //4、当临界区里没有资源时释放掉临界区 DeleteCriticalSection(&g_csB); return 0; } DWORD WINAPI Fun1Proc(LPVOID lpParameter) { // 11、两个临界区和两个线程会形成死机。线程在等待无法进入临界区g_csB。线程在等待无法进入临界区g_csA while (TRUE) { EnterCriticalSection(&g_csA); //5、该线程进入临界区g_csA Sleep(1); //6、线程进入睡眠状态 线程时间片断结束线程开始 EnterCriticalSection(&g_csB); //9、线程进入临界区g_csB,但是临界区g_csB已被线程占用故只能等待时间片断交给线程 if (tickets > 0) { Sleep( 1); cout<< "Thread1 sell tickets:"<< tickets-- << endl; } else { break; } LeaveCriticalSection(&g_csB); //退出临界区 LeaveCriticalSection(&g_csA); } return 0; } DWORD WINAPI Fun2Proc(LPVOID lpParameter) { while(TRUE) { EnterCriticalSection(&g_csB); //7、线程进入临界区g_csB Sleep(1); //8、线程进入睡眠状态线程时间片断结束线程开始 EnterCriticalSection(&g_csA); //10、线程进入临界区g_csA 但是临界区g_csA已被线程占用故只能等待时间片断交给线程 if(tickets > 0) { Sleep( 1); cout<< "Thread2 sell tickets:"<< tickets-- << endl; } else { break; } LeaveCriticalSection(&g_csA); LeaveCriticalSection(&g_csB); //退出临界区 } return 0; }
相关文章推荐
- Windows编程-- 用户方式中线程的同步---原子访问:互锁的函数家族
- Windows编程--线程和内核对象的同步-等待定时器内核对象
- 用户方式中线程的同步——Windows核心编程学习手札之八
- windows笔记-【用户方式线程同步】关键代码段
- -【用户方式线程同步】关键代码段
- Windows编程--线程和内核对象的同步-信标(信号量)内核对象
- 用户方式中线程的同步
- Windows多线程程序设计之线程同步分析(结合临界区(关键代码段))
- 多线程编程Demo[关键代码段[临界区]实现线程同步]
- Windows核心编程 第八章 用户方式中线程的同步(上)
- windows编程点滴(六)之线程同步之线程局部存储
- Windows编程那些事----线程与内核对象同步之【信标对象】
- Windows编程-- 线程和内核对象的同步 - 互斥对象内核对象
- 基于visual c++之windows核心编程代码分析(12)使用信号量同步线程
- Windows编程--线程的睡眠方式
- 基于visual c++之windows核心编程代码分析(14)使用Event同步线程
- 线程同步 关键代码段 CRITICAL_SECTION 用户模式同步对象 InitializeCriticalSection
- Windows核心编程 第八章 用户方式中线程的同步(下)
- 多线程编程之Windows同步方式
- 孙鑫VC学习笔记:第十六讲 利用关键代码段实现线程间的同步