我有个问题。我想为程序使用互斥锁。所以这是怎么回事:
我正在构造一个持有std :: timed_mutex的对象。在创建时,此对象将锁定互斥锁,因为稍后应将其解锁。现在,创建互斥锁的同一线程应该等待该互斥锁,而其他某个线程确实在后台运行。加入线程是没有选择的。
class A{
std::timed_mutex mutex;
A(){
mutex.lock();
}
bool waitForIt(int timeout){
if(mutex.try_lock_for(std::chrono::milliseconds(timeout))){
mutex.unlock();
return true;
}else{
return false;
}
}
}
当从同一线程调用waitForIt时,程序将通过并立即得到一个错误,完全忽略超时。(是的,它打算在以后解锁互斥体。它应该模仿一个事件,以便每个等待的线程都能通过)
因此在documentation中它表示此互斥体具有非递归行为。但是测试表明,例如,我可以在同一线程中多次使用.lock()而不会被阻塞。我也可以多次使用try_lock_,每次都正确!!!如果我曾经在try_lock_fors之前使用过锁,我总是会得到false。可悲的是,我需要一些东西也能阻止锁定互斥锁的同一线程。而且我不知道该用什么。我在Linux btw上编程。所以也许有本机解决方案?
我也没有在标准库中找到一个信号灯。我可以用它代替互斥锁。使用我自己的实现是可能的,但我不知道如何制作自己的信号灯。有任何想法吗?
由于人们似乎不了解它并不那么简单:
class IObservable : public IInterface{
private:
std::list<std::shared_ptr<IObserver>> observers;
public:
virtual ~IObservable(){}
void AddObserver(std::shared_ptr<IObserver> observer);
void RemoveObserver(std::shared_ptr<IObserver> observer);
void ClearObservers();
void TellCompleted(bool wasCanceled = false, std::shared_ptr<void> status = 0);
TYPEIDHASHFUNC(IObservable)
};
IObservable是线程可以向其添加观察者的东西。从IObservable派生的事物在其操作结束时调用方法TellCompleted。
class IObserver : public IInterface{
public:
virtual ~IObserver(){}
virtual CompleteResult Complete(bool wasCanceled, std::shared_ptr<void> status) = 0;
virtual bool WaitForCompletion(int timeoutInMs) = 0;
virtual bool IsCompleted() const = 0;
virtual bool WasCanceled() const = 0;
virtual std::shared_ptr<void> GetStatus() const = 0;
virtual void Reset() = 0;
TYPEIDHASHFUNC(IObserver)
};
IObserver是可以添加到IObservable的观察者。如果IObservable完成,则对添加到可观察对象的每个观察者调用Complete方法
class BasicObserver : public IObserver{
private:
bool isCompleted;
bool wasCanceled;
CompleteResult completeResult;
std::shared_ptr<void> status;
std::timed_mutex mutex;
public:
BasicObserver(CompleteResult completeResult);
~BasicObserver();
CompleteResult Complete(bool wasCanceled, std::shared_ptr<void> status);
bool WaitForCompletion(int timeoutInMs);
bool IsCompleted() const;
bool WasCanceled() const;
std::shared_ptr<void> GetStatus() const;
void Reset();
TYPEIDHASHFUNC(BasicObserver)
};
这是观察者的一种实现。它持有互斥量并实现带有超时的WaitForCompletion。 WaitForCompletion应该被阻止。当完成调用时,其互斥锁应该被解锁。超时运行时WaitForCompletion返回false
BasicObserver::BasicObserver(CompleteResult completeResult):
isCompleted(false),
wasCanceled(false),
completeResult(completeResult)
{
std::thread createThread([this]{
this->mutex.lock();
});
createThread.join();
}
BasicObserver::~BasicObserver(){
}
CompleteResult BasicObserver::Complete(bool wasCanceled, std::shared_ptr<void> status){
this->wasCanceled = wasCanceled;
this->status = status;
isCompleted = true;
mutex.unlock();
return completeResult;
}
bool BasicObserver::WaitForCompletion(int timeoutInMs){
std::chrono::milliseconds time(timeoutInMs);
if(mutex.try_lock_for(time)){
mutex.unlock();
return true;
}else{
return false;
}
}
bool BasicObserver::IsCompleted() const{
return isCompleted;
}
bool BasicObserver::WasCanceled() const{
return wasCanceled;
}
std::shared_ptr<void> BasicObserver::GetStatus() const{
return status;
}
void BasicObserver::Reset(){
isCompleted = false;
wasCanceled = false;
status = 0;
std::chrono::milliseconds time(250);
mutex.try_lock_for(time); //if this fails it might be already resetted
}
// edit:改为使用信号量(来自semaphore.h的sem_t)解决
最佳答案
您可以使用condation_variable
,特别是wait_until或wait_for。
关于c++ - C++ std::timed_mutex具有递归行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22083577/