前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++多线程编程:同步之互斥量Mutex「建议收藏」

C++多线程编程:同步之互斥量Mutex「建议收藏」

作者头像
全栈程序员站长
发布2022-09-13 11:49:14
4360
发布2022-09-13 11:49:14
举报
文章被收录于专栏:全栈程序员必看

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

目录

C++使用内核对象互斥体(Mutex)来实现线程同步锁。当两个或更多线程需要同时访问一个共享资源时,Mutex可以只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。

1. CreateMutex()

https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createmutexa

代码语言:javascript
复制
HANDLE CreateMutexA(
 LPSECURITY_ATTRIBUTES lpMutexAttributes,
 BOOL                  bInitialOwner,
 LPCSTR                lpName
);

2. ReleaseMutex()

https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-releasemutex

代码语言:javascript
复制
BOOL ReleaseMutex(
 HANDLE hMutex
);

3. WaitForSingleobject()

https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject

代码语言:javascript
复制
DWORD WaitForSingleObject(
 HANDLE hHandle,
 DWORD  dwMilliseconds
);

该函数需要传递一个内核对象句柄,如果该内核对象处于未通知状态,则该函数导致线程进入阻塞状态;如果该内核对象处于已通知状态,则该函数立即返回 WAIT_OBJECT()第二个参数指明要等待的时间(毫秒),INFINITE表示无限等待,如果第二个参数为0,那么函数立即返回。如果等待超时,该函数返 WAIT_TIMEOUT如果该函数失败,返回 WAIT_FAILED。

该函数需要传递一个内核对象句柄,如果该内核对象处于未通知状态,则该函数导致线程进入阻塞状态;如果该內核对象处于已通知状态,则该函数立即返回 WAIT_OBJECT()。第二个数指明要等待的时间(毫秒),INFINITE表示无限等待,如果第二个参数为0,那么函数立即返回。如果等待超时,该函数返 WAIT_TIMEOUT。 如果该函数失败,返回 WAIT_FAILED

4. CloseHandle()

https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle

代码语言:javascript
复制
BOOL CloseHandle(
 HANDLE hObject
);

5. 示例代码

代码语言:javascript
复制
#include<process.h>
#include<windows.h>
#include<stdio.h>


void    __cdecl   SellThread1(void* param);
void    __cdecl   SellThread2(void* param);

//100张票
int   tickets = 100;


HANDLE  hMutex = INVALID_HANDLE_VALUE;

int  main()
{ 
    

   //创建互斥体,此刻为有信号状态
   hMutex = CreateMutex(NULL, FALSE, L"售票互斥体");
    

   printf("开始卖票了!\n");

   //创建两个售票窗口 
   uintptr_t   t1 = _beginthread(SellThread1, 0, "售口窗口A");
   uintptr_t   t2 = _beginthread(SellThread2, 0, "售口窗口B");

   //无限等待两个线程全部执行完毕
   HANDLE  hArr[] = { 
    (HANDLE)t1,  (HANDLE)t2 };
   WaitForMultipleObjects(2, hArr, true, INFINITE);

   printf("卖票结束!\n");
    

   return 0;
}


void    __cdecl   SellThread1(void* param)
{ 
   
   char  *name = (char *)param;

   while (tickets>0)
   { 
   
   	//如果这个互斥体为有信号状态(没有线程拥有它),则线程获取它后继续执行
   	WaitForSingleObject(hMutex, INFINITE);
   	 if (tickets > 0)
   	{ 
   
   		Sleep(10);
   		//CPU恰好执行到这里,这个时候线程时间片到了,并且此时还剩最后一张票
   		printf("%s卖出第%d张票!\n", name, tickets--);
   	} 
   	 //释放对互斥体的拥有权,它变成有信号状态
   	 ReleaseMutex(hMutex);

   }


}
void    __cdecl   SellThread2(void* param)
{ 
   
   char  *name = (char *)param;


   while (tickets > 0)
   { 
   
   	//如果这个互斥体为有信号状态(没有线程拥有它),则线程获取它后继续执行
   	WaitForSingleObject(hMutex, INFINITE);
       	if (tickets > 0)
   		{ 
   
   			Sleep(10);
   			//CPU恰好执行到这里,这个时候线程时间片到了,并且此时还剩最后一张票
   			printf("%s卖出第%d张票!\n", name, tickets--);
   		}
   	 //释放对互斥体的拥有权,它变成有信号状态
   	 ReleaseMutex(hMutex);
   }
}

6. Mutex实现一个程序只允许允许一个实例(进程)

代码语言:javascript
复制
#include<process.h>
#include<windows.h>
#include<stdio.h>

int  main()
{ 
   
   //创建互斥体实现一个程序只允许允许一个实例(进程)
   HANDLE  hMutex   = CreateMutex(NULL, FALSE, L"售票互斥体");
   if (GetLastError() == ERROR_ALREADY_EXISTS)
   { 
   
   	printf("程序已经运行了,退出!\n");
   	getchar();

   	CloseHandle(hMutex);
   	return  0;
   }

   printf("第一次运行程序!\n");
   getchar();

   return 0;
}

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 1. CreateMutex()
  • 2. ReleaseMutex()
  • 3. WaitForSingleobject()
  • 4. CloseHandle()
  • 5. 示例代码
  • 6. Mutex实现一个程序只允许允许一个实例(进程)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档