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时程序刚刚通过并立即得到一个错误,完全忽略了超时。(是的,它打算在之后解锁互斥锁。它应该像事件一样mime,以便每个线程等待通过)
所以在documentation中它表示这个互斥锁具有非递归行为。但测试显示,例如我可以从同一个线程多次使用.lock()而不会被阻止。我也可以多次使用try_lock_for,每次都可以!如果我曾经在try_lock_fors之前使用过锁,我总是会弄错。遗憾的是,我需要的东西也会阻塞锁定互斥锁的同一个线程。我不知道该用什么。即时编程linux btw。所以也许有原生的解决方案?
我也没有在std libs.i中找到一个信号量,而不是使用互斥锁。使用我自己的实现是可能的,但我不知道如何制作我自己的信号量。任何想法?
因为人们似乎并不明白它不是那么简单:
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完成方法,则会在添加到observable
的每个观察者上调用Completeclass 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)
答案 0 :(得分:0)
您可以使用condation_variable
,特别是wait_until或wait_for。
答案 1 :(得分:0)
我会考虑重新设计你的锁定结构。 为什么不用主线程保持锁定,当事件x发生时你解锁它。如果你需要阻止一段时间,我会让线程睡眠。 让所有工作线程阻塞互斥锁试图获取锁定,如果它们需要同时运行,让它们在获取锁定后立即释放锁定。
可能使用第二个互斥锁来模拟事件x。
我想从线程1设置锁定,然后启动一个线程2 做某事(在这种情况下等待硬件输入)然后 等待线程1中的互斥锁。然后在线程2解锁互斥锁 按下硬件上的开关。我正在使用某种观察者 图案。所以我有一些可观察的东西,我添加一个观察者(在 这种情况下,A类是观察者)。在某些时候可观察到的 告诉所有添加的观察者,它完成了任务,从而解锁 互斥体。因为我们这里有硬件,可能就是硬件 锁定或传感器不起作用。所以我需要暂停 - fredlllll 3 分钟前
编辑 - 也许这会有效吗?
在线程2获得该锁定的输入块后,保持线程1中的锁定。让线程1在超时持续时间后释放锁定,也许稍微睡一会让线程通过再获取锁定。在获取互斥锁1后,让线程2释放锁定1然后在第二个互斥锁上开始阻塞,使硬件开关解锁互斥锁2导致线程2锁定互斥锁2然后解锁互斥锁2.使硬件交换机再次获取互斥锁2。