我有个问题。我想为程序使用互斥锁。所以这是怎么回事:
我正在构造一个持有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_untilwait_for

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

10-13 00:05