线程的互斥和同步(3)- Windows的互斥锁

什么是互斥锁/互斥量?

在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象;选自百度百科-互斥锁

同一时刻只有一个线程访问互斥锁,如果其他线程请求占用该互斥锁时,该请求锁的线程会被挂起。直到锁的拥有者释放该互斥锁,CPU调度到请求锁的线程占有该互斥锁,该线程被唤醒。


Windows中关于互斥锁的相关函数如下:

  • CreateCreateMutex (LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName); // 创建互斥锁
  • WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds); // 等待请求占有互斥锁
  • ReleaseMutex (HANDLE hMutex); // 释放互斥锁

  1. CreateCreateMutex 函数;表示创建一个互斥锁,
  • 参数 lpMutexAttributes : 表示安全属性,一般设置为 nullptr 表示默认安全属性。
  • 参数 bInitialOwner : 表示创建后是否立即拥有该互斥锁,TRUE 表示立即拥有; FALSE 表示不立即拥有。
  • 参数 lpName : 表示互斥锁的名称。可以设置互斥锁的名称,也可以通过名称在不同的线程中共享;如果不设置明证可以设为 nullptr
  • 返回值:成功返回互斥锁的句柄。失败返回 nullptr
  1. WaitForSingleObject 函数;表示等待请求占有互斥锁:
  • 参数 hHandle : 句柄。该函数不仅仅可以用于请求互斥锁,也可以用于比如等待线程、进程的结束;等待信号量、互斥量的占有、和等到信号。
  • 参数 dwMilliseconds : 表示毫秒数。设置为 INFINITE 表示无限等待下去。
  • 返回值:
返回值说明
WAIT_FAILED表示函数 WaitForSingleObject 调用失败,可以通过函数 GetLastError() 获取错误码
WAIT_OBJECT_0表示成功等待到设置的对象
WAIT_TIMEOUT表示等待超时
WAIT_ABANDONED如果对象时Mutex,表示持有Mutex对象的线程已经结束,但是没有释放该互斥锁;此时该Mutex对象处于废弃状态。其行为未知,不建议使用
  1. ReleaseMutex 函数,表示释放互斥锁。
  • 参数 hMutex 互斥锁的句柄

下面是个关于互斥锁的使用的简单示例,同样使用了 CThread
头文件:

class WinMutexThread : public CThread
{
public:
	void run(void) override;

	// 初始化Mutex,用于创建互斥锁
	static void initMutex(void);

private:
	// 互斥锁
	static HANDLE m_mutexHandle;
};

源文件:

#include <iostream>

HANDLE WinMutexThread::m_mutexHandle = nullptr;
int number = 0;

void WinMutexThread::run(void)
{
	while (1)
	{
		if (::WaitForSingleObject(m_mutexHandle, INFINITE) == WAIT_OBJECT_0)
		{
			std::cout << "Current Thread: " << ::GetCurrentThreadId() \
			          << ", Value: " << number++ << std::endl;

			::ReleaseMutex(m_mutexHandle);
		}

		Sleep(1000);
	}
}

void WinMutexThread::initMutex(void)
{
	m_mutexHandle = ::CreateMutex(nullptr, FALSE, nullptr);
}

在run() 函数中,我们简单的请求互斥锁,并打印该线程ID和使全局变量的值自增1

调用

int main(int argc, char** argv)
{
	// 创建互斥锁
	WinMutexThread::initMutex();

	// 创建三个线程
	WinMutexThread thread1;
	WinMutexThread thread2;
	WinMutexThread thread3;
	// 开启线程
	thread1.start();
	thread2.start();
	thread3.start();
	// 等待
	thread1.wait();
	thread2.wait();
	thread3.wait();

	system("pause");
	return 0;
}

运行结果如下:
Current Thread: 12632, Value: 0
Current Thread: 13096, Value: 1
Current Thread: 18652, Value: 2
Current Thread: 12632, Value: 3
Current Thread: 13096, Value: 4
Current Thread: 18652, Value: 5
Current Thread: 12632, Value: 6
Current Thread: 13096, Value: 7
Current Thread: 18652, Value: 8
Current Thread: 12632, Value: 9
Current Thread: 13096, Value: 10
Current Thread: 18652, Value: 11


作者:douzhq
个人博客主页:不会飞的纸飞机
文章同步页(可下载完整代码)线程的互斥和同步(3)- Windows的互斥锁

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页