pos*_*man 5 c++ mutex semaphore locking
我有两个方法“log”和“measure”,它们永远不应该同时执行。所以我尝试使用“std::mutex”来执行此操作,如下所示:
void log(std::string message)
{
mtx.lock();
someLogFunctionality();
mtx.unlock();
}
void measure()
{
mtx.lock();
someMeasureFunctionality();
mtx.unlock();
}
Run Code Online (Sandbox Code Playgroud)
现在事实证明,还可以在不锁定的情况下并行多次调用“log”,这同样适用于“measure”。(原因:someLogFunctionality() 和 someMeasureFunctionality() 互相干扰,但同一个方法可能会并行调用多次)
然后我查看了“std::shared_mutex”,但对我来说有两个问题:
1.)使用shared_mutex,我只能将lock_shared用于其中一种方法(日志或测量),但另一个方法必须使用排他锁(并且不能再次并行执行多次)
void log(std::string message)
{
mtx.lock_shared();
someLogFunctionality();
mtx.unlock_shared();
}
void measure()
{
mtx.lock(); // This should also be shared but among another "group"
someMeasureFunctionality();
mtx.unlock();
}
Run Code Online (Sandbox Code Playgroud)
2.)我无法使用C++17(受我正在使用的环境的限制)
您对我如何实现这一点有什么建议吗?
根据 alexb 的回复,我编写了以下互斥类,该类目前对我有用(到目前为止仅在简单的多线程示例应用程序中进行了尝试)
请注意,它无法防止“饥饿”。简而言之:如果频繁调用 lockLogging(反之亦然),则不能确保 lockMeasure 能够获得锁定。
class MyMutex
{
private:
std::atomic<int> log_executors;
std::atomic<int> measure_executors;
std::mutex mtx;
std::condition_variable condition;
public:
MyMutex() : log_executors(0), measure_executors(0) {}
~MyMutex() {}
void lockMeasure()
{
std::unique_lock<std::mutex> lock(mtx);
while(log_executors) {
condition.wait(lock);
}
measure_executors++;
}
void unlockMeasure()
{
std::unique_lock<std::mutex> lock(mtx);
measure_executors--;
if (!measure_executors)
{
condition.notify_all();
}
}
void lockLogging()
{
std::unique_lock<std::mutex> lock(mtx);
while(measure_executors) {
condition.wait(lock);
}
log_executors++;
}
void unlockLogging()
{
std::unique_lock<std::mutex> lock(mtx);
log_executors--;
if (!log_executors)
{
condition.notify_all();
}
}
static MyMutex& getInstance()
{
static MyMutex _instance;
return _instance;
}
};
Run Code Online (Sandbox Code Playgroud)
用法:
void measure()
{
MyMutex::getInstance().lockMeasure();
someMeasureFunctionality();
MyMutex::getInstance().unlockMeasure();
}
void log()
{
MyMutex::getInstance().lockLogging();
someLogFunctionality();
MyMutex::getInstance().unlockLogging();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
503 次 |
| 最近记录: |