用内核对象进行线程同步——互斥量内核对象
来源:互联网 发布:颜值高的游戏本知乎 编辑:程序博客网 时间:2024/05/22 05:03
互斥内核对象用来确保一个线程独占对一个资源的访问。互斥亮和关键段的的行为完全相同,但关键段是用户模式下的同步对象,意味着互斥量比关键段慢。
内核对象包含一个使用计数(内核对象都有)、线程ID及一个递归计数
线程ID:标识当前占用这个互斥量的是系统中的哪个线程。ID为0,则互斥量不被任何线程占用,处于触发状态;否则处于未触发状态
递归计数:表示这个线程占用互斥量的次数
创建互斥量
// bInitialOwner// FALSE:互斥量不为任何线程所占用,处于触发状态; // TRUE:互斥量被调用线程线程所占用,处于未触发状态HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName );
打开互斥量
HANDLE OpenMutex( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName );
释放互斥量
BOOL ReleaseMutex(HANDLE hMutex);
某一个线程一旦成功等到了互斥量(即互斥量处于触发状态),则线程就已经独占了受保护的资源,此时互斥量变为未触发状态,其他任何通过等待该互斥量的线程都不能访问资源。当线程结束时必须调用ReleaseMutex释放互斥量,使互斥量变为触发状态,这样系统会选择一个其他等待该互斥量的线程执行。
互斥量内核对象例子
#include "stdafx.h"#include <windows.h> #include <process.h> #include <iostream>using namespace std;int g_x = 0;HANDLE h_Mutex;// 写入线程UINT WINAPI ThreadFunc1(PVOID pArguments){ // 互斥量从触发状态变为未触发状态 // 在等待函数内部,会检测该互斥量的线程ID是否为0, // 如果是,即互斥量处于触发状态,则把线程ID设为调用线程的ID,递归计数设为1,此时互斥量处于未触发状态; // 如果线程ID是不为0,则线程继续等待 WaitForSingleObject(h_Mutex, INFINITE); int n = 0; while (n < 5) { g_x += n; n++; cout << "ThreadFunc1.." << endl; } // 互斥量从未触发状态变为触发状态 // ReleaseMutex 会把互斥量对象的递归计数减1, // 等待了几次,ReleaseMutex 就要调用几次把递归计数变为0,此时线程ID也会设为0,这样就触发了对象。 ReleaseMutex(h_Mutex); _endthreadex(0); return 0;}// 读线程UINT WINAPI ThreadFunc2(PVOID pArguments){ WaitForSingleObject(h_Mutex, INFINITE); cout << "ThreadFunc2.." << endl; ReleaseMutex(h_Mutex); _endthreadex(0); return 0;}// 写入线程UINT WINAPI ThreadFunc3(PVOID pArguments){ WaitForSingleObject(h_Mutex, INFINITE); int n = 0; while (n < 5) { g_x += n; n++; cout << "ThreadFunc3.." << endl; } ReleaseMutex(h_Mutex); _endthreadex(0); return 0;}int _tmain(int argc, _TCHAR* argv[]){ HANDLE handle[3]; unsigned unThreadID[3]; cout << "g_x initial value: " << g_x << endl; // 创建一个处于触发状态的互斥量 h_Mutex = CreateMutex(NULL, FALSE, _T("Thread_Mutex")); handle[0] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc1, NULL, 0, &unThreadID[0]); handle[1] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc2, NULL, 0, &unThreadID[1]); handle[2] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc3, NULL, 0, &unThreadID[2]); g_x = 100; cout << "g_x Final value: " << g_x << endl; getchar(); CloseHandle(h_Mutex); return 0;}
阅读全文
0 0
- 用内核对象进行线程同步——互斥量内核对象
- 用内核对象进行线程同步——事件内核对象
- 用内核对象进行线程同步——信号量内核对象
- 用内核对象进行线程同步1
- windows 用内核对象进行线程同步
- 用内核对象进行线程同步
- 用内核对象进行线程同步
- 用内核对象同步线程
- 内核对象和线程同步—WaitForSingleObject
- 《Windows核心编程》——九 用内核对象进行线程同步
- Windows核心编程:用内核对象进行线程同步
- 第九章:用内核对象进行线程同步
- 第九章:用内核对象进行线程同步(一)
- 第九章:用内核对象进行线程同步(二) .
- Windows核心编程 用内核对象进行线程同步
- windows核心编程-9.用内核对象进行线程同步
- windows核心编程-用内核对象进行线程同步
- windows核心编程---用内核对象进行线程同步
- 【Maven用户手册】Maven之pom.xml配置文件详解
- java的集合学习
- Js_Dom(6)__Dom基础<Bom,window,计时器以及空野指针>
- signal(SIGCHLD, SIG_IGN)和signal(SIGPIPE, SIG_IGN);
- Socket异步通信及心跳包同时响应逻辑分析(最后附Demo)。
- 用内核对象进行线程同步——互斥量内核对象
- react.js路由(4.x):模拟一个用户登录2(登录判断、路由的多种加载方式)
- 网卡、交换机、网桥、路由器、网关分别工作于OSI模型哪一层
- index的注释与理解(1)遮罩层如何写之(二).1
- The Balance (hdu1709) 母函数
- 《战狼2》破34亿,大数据告诉你什么样的电影IP才能火?
- 想学习推荐系统,如何从小白成为高手?
- 2017/8/6 第十四天
- FastReport.Net 报表连接数据库