C ++条件等待停止执行

时间:2015-07-07 08:38:14

标签: c++ multithreading c++11 concurrency

我有以下类方法:

myclass::concurFnc(bool changingVar )
{
    int i;
    mIdMutex.lock();
    i = mId++;
    mIdMutex.unlock;

    std::cout << "Try Waiting: " << i << std::endl;
    std::mutex waitValidMutex;
    std::unique_lock<std::mutex> l(waitValidMutex);
    mNoOtherThreadDiffCompareVal.wait(l, [this, &changingVar]()
    {
        mSemMutex.lock();
        bool result = false;
        if(myclass::staticVar == changingVar)
        {
            std::cout << "Same var : " << changingVar << i << std::endl;
            result = true;
            --mSem;
        } else if(mSem == 1)
        {
            std::cout << "Only one in crit section: " << i << std::endl;
            --mSem;
            myclass::staticVar = changingVar;
            result = true;
        } else
        {
            std::cout << "wait: " << i << std::endl;
            result = false;
        }
        std::cout << "Sem is now " << mSem << std::endl;
        mSemMutex.unlock();
        return result;
    });

    //DO STUFF

    mSemMutex.lock();
    ++mSem;
    std::cout << "In the end sem is: " << mSem << std::endl;
    mSemMutex.unlock();
    mNoOtherThreadDiffCompareVal.notify_all();
}

//class Member Variables
std::mutex mSemMutex;
std::mutex mIdMutex;
std::condition_variable mNoOtherThreadDiffCompareVal;
int32_t mSem;
int32_t mId;

myclass::myclass() : mSem(1), mId(0)
{
}

void myclass::startThreads()
{
    const int AMOUNT_OF_PROCESSES = 3
    std::vector<std::shared_ptr<boost::thread> > processes;
    for (size_t t_id = 0; t_id < AMOUNT_OF_PROCESSES; ++t_id) 
    {
        bool changingVar = getVarSomewhere();
        std::shared_ptr<boost::thread> thread_ptr(new boost::thread(&myclass::concurFnc, this, changingVar));
        processes.push_back(thread_ptr);
    }

    for (size_t t_id = 0; t_id < AMOUNT_OF_PROCESSES; ++t_id) {
        processes[t_id]->join();
    }
}

如果changingVar与当前位于// DO STUFF内的所有其他调用者相同(或者如果是唯一的调用者),则应该允许输入// DO STUFF部分 该函数从boost :: threads中的函数调用。

有时会发生执行停止,因为它仍然在等待,尽管mSem为1并且应该调用notify_all()

执行停止前的输出是:

wait: 3248
Sem is now 0
Try Waiting: 3249
wait: 3249
Sem is now 0
In the end sem is: 1
Only one in crit section: 3249
Sem is now 0
Try Waiting: 3250
wait: 3250
Sem is now 0
In the end sem is: 1
Only one in crit section: 3250
Sem is now 0
In the end sem is: 1
Try Waiting: 3251
Same comp val : 0 of: 3251
Sem is now 0
.In the end sem is: 1

到目前为止,我无法真正重现它。

该计划再次开始运作。 Mabey是因为我把gdb附加到它上面,或者某种程度上有很大的延迟。

1 个答案:

答案 0 :(得分:1)

条件变量的使用模式非常奇怪。

传入条件变量的wait函数的互斥锁应始终是保护您正在等待的条件的互斥锁,这里似乎是mSemMutex

这是有道理的,因为要检查是否满足等待条件,您仍需要锁定此互斥锁。考虑到这一点,你可以完全摆脱waitValidMutex并用mSemMutex替换它的所有用途。

另请注意,目前,由于waitValidMutex是本地互斥锁,因此实际上risk undefined behavior when calling wait

  

如果lock.mutex()与该互斥锁不是同一个互斥锁,则调用此函数   由当前正在等待的所有其他线程使用   条件变量是未定义的行为。