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

C++多线程编程:同步之互斥量Mutex「建议收藏」文章目录5.示例代码文章目录1.CreateMutex()2.ReleaseMutex()3.WaitForSingleobject()4.CloseHandle()5.示例代码6.Mutex实现一个程序只允许允许一个实例(进程)5.示例代码文章目录1.CreateMutex()2.ReleaseMutex()3.WaitForSingleobject()4.CloseHandle()5.示例代码6.Mutex实现一个程序只允许允许一个实例(进程))5.示例代码文章目录1

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

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

1. CreateMutex()

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

HANDLE CreateMutexA(
 LPSECURITY_ATTRIBUTES lpMutexAttributes,
 BOOL                  bInitialOwner,
 LPCSTR                lpName
);

2. ReleaseMutex()

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

BOOL ReleaseMutex(
 HANDLE hMutex
);

3. WaitForSingleobject()

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

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

BOOL CloseHandle(
 HANDLE hObject
);

5. 示例代码

#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实现一个程序只允许允许一个实例(进程)

#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.net/153213.html原文链接:https://javaforall.net

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


相关推荐

发表回复

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

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