什么是互斥锁/互斥量?
在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象;选自百度百科-互斥锁。
同一时刻只有一个线程访问互斥锁,如果其他线程请求占用该互斥锁时,该请求锁的线程会被挂起。直到锁的拥有者释放该互斥锁,CPU调度到请求锁的线程占有该互斥锁,该线程被唤醒。
Windows中关于互斥锁的相关函数如下:
返回值 | 说明 |
---|---|
WAIT_FAILED | 表示函数 WaitForSingleObject 调用失败,可以通过函数 GetLastError() 获取错误码 |
WAIT_OBJECT_0 | 表示成功等待到设置的对象 |
WAIT_TIMEOUT | 表示等待超时 |
WAIT_ABANDONED | 如果对象时Mutex,表示持有Mutex对象的线程已经结束,但是没有释放该互斥锁;此时该Mutex对象处于废弃状态。其行为未知,不建议使用 |
下面是个关于互斥锁的使用的简单示例,同样使用了 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