gpt4 book ai didi

C++ std::timed_mutex 具有递归行为

转载 作者:太空宇宙 更新时间:2023-11-04 13:54:34 25 4
gpt4 key购买 nike

我有一个问题。我想为我的程序使用互斥体。所以会发生什么:我正在构造一个包含 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 时,程序刚刚通过并立即得到一个 false,完全忽略了超时。(是的,它的目的是之后解锁互斥锁。它应该模仿一个事件,以便每个等待的线程都能通过)

所以在documentation它说这个互斥量具有非递归行为。但是测试显示,例如我可以从同一个线程多次使用 .lock() 而不会被阻塞。我也可以多次使用 try_lock_for 并且每次都是真的!!!如果我在 try_lock_fors 之前使用 lock,我总是得到 false。可悲的是,我需要一些东西来阻止锁定互斥锁的同一个线程。我不知道该用什么。顺便说一句,我在 Linux 上编程。那么也许有本地解决方案?

我也没有在标准库中找到信号量。我可以用它来代替互斥体。使用我自己的实现是可能的,但我不知道如何制作我自己的信号量。有什么想法吗?

因为人们似乎不明白事情没那么简单:

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 应该阻止。当调用 complete 时,它​​的互斥量应该被解锁。当超时运行时 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
}

//编辑:通过使用信号量解决(来自 semaphore.h 的 sem_t)

最佳答案

您可以使用 condation_variable,特别是 wait_untilwait_for .

关于C++ std::timed_mutex 具有递归行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22083577/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com