C++:如何简化线程锁定
C++: How To Simplified Thread Lock?
我是C++的新手。在学习线程如何工作时,我发现在开始时调用WaitForSingleObject(x),在结束时调用ReleaseMutex(x)非常烦人。所以我写了一节课来为我做这件事,但我不确定影响,我做得对吗。想知道有没有更简单的方法来实现同样的目的?我是这样做的:
class MutexLock {
public:
MutexLock(HANDLE hMutex) {
m_hMutex = hMutex;
}
void Lock() {
WaitForSingleObject((m_hMutex), INFINITE);
}
~MutexLock() {
if (m_hMutex != NULL) {
ReleaseMutex(m_hMutex);
std::cout << "Mutex released." << std::endl;
}
}
private:
HANDLE m_hMutex;
};
以及我如何使用该类:
class TestMutex
{
public:
TestMutex(void) {
m_mutex = CreateMutex(NULL, FALSE, NULL);
std::cout << "Mutex created." << std::endl;
}
~TestMutex(void) {
if (m_mutex != NULL)
CloseHandle(m_mutex);
}
void Func1(void) {
MutexLock ml(m_mutex);
ml.Lock();
std::cout << "Func1: Owning mutex." << std::endl;
std::cout << "Press enter key to end this." << std::endl;
ReadKey(GetStdHandle(STD_INPUT_HANDLE));
}
void Func2(void) {
MutexLock ml(m_mutex);
ml.Lock();
//std::cout << "Press enter key to start this." << std::endl;
//ReadKey(GetStdHandle(STD_INPUT_HANDLE));
std::cout << "Func2: Owning mutex." << std::endl;
std::cout << "Press enter key to end this." << std::endl;
ReadKey(GetStdHandle(STD_INPUT_HANDLE));
}
private:
HANDLE m_mutex;
};
在主要功能:
int _tmain(int argc, _TCHAR* argv[])
{
TestMutex * tm = new TestMutex();
HANDLE aThread[2];
for (int i = 0; i < 2; i++)
{
aThread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, (LPVOID)tm, 0, 0);
}
WaitForMultipleObjects(2, aThread, TRUE, INFINITE);
for (int i = 0; i < 2; i++)
{
CloseHandle(aThread[i]);
}
delete tm;
ReadKey(GetStdHandle(STD_INPUT_HANDLE));
return 0;
}
其他人通常是这样做线程锁定的吗?
实际上,您允许类API的使用者滥用它,而您可以很容易地防止这种情况发生。施工结束后,他必须给锁打一次电话。他可能不知道这一点,忘记打电话,或者打两次。
更简单、更不容易出错的方法是将锁方法设为私有方法,并从构造函数中调用它。
但是,正如其他评论者所写的那样,最好是使用现有的图书馆。除了其他人提到的,Qt还有一个很好的QMutexLocker类。
我不相信它会比你现有的"简单"得多。您需要相互排除由多个进程修改的共享变量。您可能会遇到一种"只读"类型的情况,其中不需要互斥,但这无助于简化。
销毁互斥锁(当它超出范围时)可能是最好的方法,我已经看到许多线程库使用完全相同的方法。可移植工具库(PortableToolsLibrary,PTLib)是一个包含线程抽象的抽象库,当互斥对象超出范围时,它会释放互斥对象,但您仍然必须使用它们。但是,您还应该跟踪针对互斥体的调用和释放次数,以便在其他线程可用时向其发出信号。
此外,正如Bgie在回答中指出的那样,您确实需要保护您的代码永远不要相信其他程序员,包括你未来的自己。
但是,当范围剩下时释放锁的想法是一个很好的第一个一般实现,只需要一些额外的工作:)。
(根据Bgie的评论进行编辑)
相关文章:
- 如何检查线程是否锁定
- 在两个线程上读/写 64 位,无互斥/锁定/原子
- 如何在实时应用程序中锁定线程
- 锁定来自其他线程的类成员
- 当只有一个线程主要使用该对象而其他线程很少使用它时,如何最小化该对象的互斥锁锁定?
- 将线程锁定很长时间
- C++将互斥锁锁定为来自另一个线程
- 在以读取为主的多线程程序中,可以使用原子来减少锁定吗
- std::weak_ptr<T>::锁定线程安全吗?
- 线程锁定互斥锁的速度比 std::conditional_variable::wait() 快
- C 优化导致线程锁定
- 是否可以在C++中使用std::atomic_flag获得线程锁定机制
- mutex::lock() 检查一次解锁状态是否已经被另一个线程锁定?
- C++11中的基本线程锁定
- boost线程锁定错误
- 当一个线程锁定一个大映射时,如何避免冻结其他线程
- 导致c++ 11 std::互斥锁将被阻塞的线程锁定到被动等待状态
- shared_ptr.get()可以被多个线程调用,而另一个线程锁定并调用shared_ptr.swap()吗?
- 发现可能由于线程锁定(可能)导致的性能问题
- C++:如何简化线程锁定