互斥量Mutex的简单应用

互斥量Mutex的简单应用一、互斥量的简单介绍互斥量是一个内核对象,它用来确保一个线程独占一个资源的访问。互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源。使用互斥量Mutex主要将用到四个函数。下面是这些函数的原型和使用说明。1) CreateMutex函数功能:创建互斥量函数原型:HANDLECreateMutex(LPSECURITY_ATTRIBUTES…

大家好,又见面了,我是你们的朋友全栈君。

一、互斥量的简单介绍

互斥量是一个内核对象,它用来确保一个线程独占一个资源的访问。互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源。

使用互斥量Mutex主要将用到四个函数。下面是这些函数的原型和使用说明。

1) CreateMutex

函数功能:创建互斥量

函数原型:

HANDLE CreateMutex(
  LPSECURITY_ATTRIBUTES lpMutexAttributes,
  BOOL                  bInitialOwner,     
  LPCTSTR               lpName
);

函数说明:

第一个参数表示安全控制,一般直接传入NULL。

第二个参数用来确定互斥量的初始拥有者。如果传入TRUE表示互斥量对象内部会记录创建它的线程的线程ID号并将递归计数设置为1,由于该线程ID非零,所以互斥量处于未触发状态。如果传入FALSE,那么互斥量对象内部的线程ID号将设置为NULL,递归计数设置为0,这意味互斥量不为任何线程占用,处于触发状态。

第三个参数用来设置互斥量的名称,在多个进程中的线程就是通过名称来确保它们访问的是同一个互斥量。

函数返回值:

成功返回一个表示互斥量的句柄,失败返回NULL。

2)OpenMutex

函数功能:打开互斥量,相当于使用互斥量

函数原型:

HANDLE OpenMutex(
 DWORD       dwDesiredAccess,
 BOOL        bInheritHandle,
 LPCTSTR     lpName     //名称
);

函数说明:

第一个参数表示访问权限,对互斥量一般传入MUTEX_ALL_ACCESS。详细解释可以查看MSDN文档。

第二个参数表示互斥量句柄继承性,一般传入TRUE即可。

第三个参数表示名称。某一个进程中的线程创建互斥量后,其它进程中的线程就可以通过这个函数来找到这个互斥量。

函数返回值:

成功返回一个表示互斥量的句柄,失败返回NULL。

3)ReleaseMutex

函数功能:触发互斥量,相当于解除对互斥量的占用

函数原型:

BOOL ReleaseMutex(HANDLE hMutex);

函数返回值:

成功返回TRUE,失败返回FALSE

4)CloseHandle

函数功能:清理互斥量,即释放内核对象

函数原型:

BOOL CloseHandle(
HANDLE hObject
);

函数说明:

hObject :代表一个已打开对象handle。

函数返回值:

成功返回TRUE,失败返回FALSE,可以调用GetLastError()获知失败原因。

二、互斥量的示例使用

本文章将使用3个进程示例互斥量的使用,相当于互斥量阻止三个进程同时使用同一块内存。但在贴代码之前先简要说明一下WaitForSingleObject函数,该函数用于检测hHandle事件的信号状态。

WaitForSingleObject

函数功能:用来检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起,如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。

函数原型:

DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);

函数说明:

hHandle:对象句柄。可以指定一系列的对象,如Event、Job、Memory resource notification、Mutex、Process、Semaphore、Thread、Waitable timer等。

dwMilliseconds:定时时间间隔,单位为milliseconds(毫秒).如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。如果dwMilliseconds为0,对象没有被触发信号,函数不会进入一个等待状态,它总是立即返回。如果dwMilliseconds为INFINITE,对象被触发信号后,函数才会返回。

函数返回值:

WAIT_ABANDONED 0x00000080:当hHandle为mutex时,如果拥有mutex的线程在结束时没有释放核心对象(通过调用ReleaseMutex函数释放)会引发此返回值。

WAIT_OBJECT_0 0x00000000 :指定的对象出有有信号状态

WAIT_TIMEOUT 0x00000102:等待超时

WAIT_FAILED 0xFFFFFFFF :出现错误,可通过GetLastError得到错误代码

以上,就是WaitForSingleObject函数的简要介绍。

接下来将介绍3个进程示例互斥量的使用:

进程1(创建互斥量):

#include <stdio.h>
#include <Windows.h>
const TCHAR MUTEX_NAME[] = L"Mutext_test";

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hMutex = CreateMutex(NULL, TRUE, MUTEX_NAME);
	printf("互斥量已经创建,现在按任意键触发互斥量\n");
	getchar();
	ReleaseMutex(hMutex);
	printf("互斥量已经触发\n");
	CloseHandle(hMutex);
	return 0;
}

进程2(打开互斥量):

#include <stdio.h>

const TCHAR MUTEX_NAME[] = L"Mutext_test";

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, MUTEX_NAME);
	if (hMutex == NULL)
	{
		printf("打开互斥量失败\n");
		getchar();
		return 0;		
	}

	printf("等待中...\n");
	DWORD dwResult = WaitForSingleObject(hMutex, 200 * 1000);
	switch (dwResult)
	{
	case WAIT_ABANDONED:
		printf("拥有互斥量的进程意外终止\n");
		break;
	case WAIT_OBJECT_0:
		printf("已经收到信号\n");
		break;
	case WAIT_TIMEOUT:
		printf("信号未在规定时间内送到\n");
		break;
	default:
		break;
	}

    // PS:要在释放互斥量之前加个getchar函数,这样有助于观察进程3在等待使用互斥量状态
	getchar();
	ReleaseMutex(hMutex);
	CloseHandle(hMutex);
	return 0;
}

进程3(打开互斥量):

const TCHAR MUTEX_NAME[] = L"Mutext_test";

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, MUTEX_NAME);
	if (hMutex == NULL)
	{
		printf("打开互斥量失败\n");
		getchar();
		return -1;
	}

	printf("等待中...\n");
	DWORD nResult = WaitForSingleObject(hMutex, 20 * 10000);
	switch(nResult)
	{
	case WAIT_ABANDONED:
		printf("创建互斥量进程已被废弃\n");
		break;
	case WAIT_OBJECT_0:
		printf("成功接收到信号\n");
		break;
	case WAIT_TIMEOUT:
		printf("等待时间已超时\n");
		break;
	default:
		break;
	}
	getchar();
	ReleaseMutex(hMutex);
	CloseHandle(hMutex);
	return 0;
}

执行结果如下:

互斥量Mutex的简单应用

互斥量Mutex的简单应用

当testOpenMutex1.exe 成功接收到信号后按下任意键后就会解除对该互斥量的使用,从而使testOpenMutex.exe可以使用该互斥量。

互斥量Mutex的简单应用

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/153199.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • SQL Server内存

    SQL Server内存

    2021年11月28日
  • 2019/7/3

    2019/7/31176E-Coverit!树的题常与层数,出度有关

  • 神经网络可视化工具有哪些_神经网络可视化函数plot

    神经网络可视化工具有哪些_神经网络可视化函数plot1.下载安装Netron下载链接:https://github.com/lutzroeder/netron/releases/tag/v3.5.4安装命令:sudodpkg-inetron_3.5.4_amd64.deb2.使用Netron进行网络可视化首先在终端输入netron命令接着打开基于pytorch的.p…

  • 手机号码归属地服务[转载]「建议收藏」

    手机号码归属地服务[转载]「建议收藏」服务地址:http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmxWebXml.com.cn国内手机号码归属地查询WEB服务,提供最新的国内手机号码段归属地数据,每月更新。使用本站WEB服务请注明或链接本站:http://www.webxml.com.cn/感谢大家的支持!支持下列操作。有关正式定义,请查看服务说明。…

  • pytest指定用例_pytest如何循环执行用例

    pytest指定用例_pytest如何循环执行用例前言测试用例在设计的时候,我们一般要求不要有先后顺序,用例是可以打乱了执行的,这样才能达到测试的效果.有些同学在写用例的时候,用例写了先后顺序,有先后顺序后,后面还会有新的问题(如:上个用例返回

  • SQL Server中QUOTENAME函数的使用

    SQL Server中QUOTENAME函数的使用–函数QUOTENAME–功能:返回带有分隔符的Unicode 字符串,分隔符的加入可使输入的字符串成为有效的Microsoft SQL Server 2005 分隔标识符。–语法QUOTENAME ( character_string [ , quote_character ] ) –举例说明:–比如你有一个表,名字叫index–你有一个动

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号