c++多线程重点难点(三)Mutex

c++多线程重点难点(三)Mutex互斥量互斥量是一个内核对象,它用来确保一个线程独占一个资源的访问。互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源。使用互斥量Mutex主要将用到四个函数创建互斥量:CreateMutex函数返回一个互斥量的句柄或者NULL打开互斥量:OpenMutex函数返回一个互斥量的句柄或者NULL触发互斥量:ReleaseMutex访问互斥资源前应该要调用等待函数,结

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

互斥量

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

创建互斥量:CreateMutex
函数返回一个互斥量的句柄或者NULL

打开互斥量:OpenMutex
函数返回一个互斥量的句柄或者NULL

触发互斥量:ReleaseMutex
访问互斥资源前应该要调用等待函数,结束访问时就要调用ReleaseMutex()来表示自己已经结束访问,其它线程可以开始访问了。

销毁互斥量:CloseHandle
内核对象的销毁都可以用这个方法

要注意的是:

1.互斥量解决不了线程间的同步问题
2.互斥量和关键段一样拥有“线程拥有权”
3.遗弃特性:
比如有一个占用互斥量的线程在调用ReleaseMutex()触发互斥量前就意外终止了(相当于该互斥量被“遗弃”了),那么所有等待这个互斥量的线程是否会由于该互斥量无法被触发而一直阻塞?这显然不合理。因为占用某个互斥量的线程既然终止了那足以证明它不再使用被该互斥量保护的资源,所以这些资源完全并且应当被其它线程来使用。因此在这种“遗弃”情况下,系统自动把该互斥量内部的线程ID设置为0,并将它的递归计数器复置为0,表示这个互斥量被触发了。然后系统将“公平地”选定一个等待线程来完成调度(被选中的线程的WaitForSingleObject()会返回WAIT_ABANDONED_0)。

下面有两个程序用来实现mutex的遗弃特性,运用这两个程序时要先启动程序一再启动程序二,将程序一中//exit(0);前面的注释符号去掉,这样程序一在触发互斥量之前就会因为执行exit(0);语句而且退出,程序二会收到WAIT_ABANDONED消息并输出“拥有互斥量的进程意外终止”:

//程序一
#include <stdio.h>
#include <conio.h>
#include <windows.h>
const char MUTEX_NAME[] = "Mutex_MoreWindows";
int main()
{
    HANDLE hMutex = CreateMutex(NULL, TRUE, MUTEX_NAME); //创建互斥量
    printf("互斥量已经创建,现在按任意键触发互斥量\n");
    getch();
    //exit(0);
    ReleaseMutex(hMutex);
    printf("互斥量已经触发\n");
    CloseHandle(hMutex);
    return 0;
}
//程序二
#include <stdio.h>
#include <windows.h>
const char MUTEX_NAME[] = "Mutex_MoreWindows";
int main()
{
    HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, MUTEX_NAME); //打开互斥量
    if (hMutex == NULL)
    {
        printf("打开互斥量失败\n");
        return 0;
    }
    printf("等待中....\n");
    DWORD dwResult = WaitForSingleObject(hMutex, 20 * 1000); //等待互斥量被触发
    switch (dwResult)
    {
    case WAIT_ABANDONED:
        printf("拥有互斥量的进程意外终止\n");
        break;

    case WAIT_OBJECT_0:
        printf("已经收到信号\n");
        break;

    case WAIT_TIMEOUT:
        printf("信号未在规定的时间内送到\n");
        break;
    }
    CloseHandle(hMutex);
    return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/153218.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【面试】50道经典计算机网络面试题

    【面试】50道经典计算机网络面试题

    2022年2月20日
    39
  • python pyc文件使用_python怎么打开pyc文件

    python pyc文件使用_python怎么打开pyc文件首先使用百度搜索“ultraEdit”,进入到如图所示的官网下载文件。进入到ultraEdit官网的下载界面,我们选择如图所示的试用版本下载,我们进入到具体的下载界面后,点击下载中文安装版。下载好,我们使用鼠标左键双击软件安装包,进入到安装界面后点击安装,使用默认安装就可以了,无需修改安装文件路径。安装好了后,我们在电脑桌面使用鼠标左键双击ultraEdit的快捷方式,打开后进入到ultraEdi…

    2022年6月24日
    22
  • futureTask用法

    futureTask用法futureTask用法深入学习FutureTask主要讲解了如何去使用futureTask来创建多线程任务,并获取任务的结果。Callable接口:实现这个接口的类,可以在这个类中定义需要执行的方法和返回结果类型。MyTask.java类publicclassMyTaskimplementsCallable<Object>{p…

    2022年6月16日
    34
  • kali linux木马免杀工具

    kali linux木马免杀工具1.VenomShellcodeGenerator

    2022年8月20日
    5
  • printwriter报错_java输出print和println

    printwriter报错_java输出print和println我是一位长期读者,但是第一次写作.我目前正在尝试在代码库中使用AspectJ实现一个记录器.AspectJ似乎运行良好,但我遇到了非常奇怪的Java错误.我是一个长期的C和.Net开发人员,他仍然适应Java的世界,所以如果这是一个愚蠢的问题我很抱歉.我的代码试图捕获异常,并将相关信息记录到文本文件中.陷阱工作正常,但我注意到,当我部署时,我没有得到任何数据.我在Java反编译器中打开了我的类文…

    2022年8月10日
    6
  • Python字符串使用详解

    Python字符串使用详解除了数字,Python中最常见的数据类型就是字符串,无论那种编程语言,字符串无处不在。例如,从用户哪里读取字符串,并将字符串打印到屏幕显示出来。字符串是一种数据结构,这让我们有机会学习索引和切片——用于从字符串中提取子串的方法。1字符串索引在Python语法支持中,我们简单的阐述过字符串的使用,现在我们看看python程序在处理字符串时,如何对其进行索引,打印出其中的每个字符串。我们输入一个字符串:’你好,Lucky’,Python使用方括号[]来对字符串进行索引,方括号内的数字0~n表

    2022年10月25日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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