Многопоточность с помощью std :: Vector в C ++

0

Я хочу создать два потока, которые обращаются к вектору одновременно, так что один раз удерживает элементы на обратной стороне вектора каждые 10 миллисекунд, а другой просто контролирует вектор, чтобы увидеть, изменился ли его размер. Здесь я получаю сообщение об ошибке "unlock of unowned mutex", не могли бы вы рассказать мне, почему.

class SafeVec
{
public:
    SafeVec(){}
    ~SafeVec(){}
    void safePushBack(int val)
    {
        vecMutex.lock();
        vec.push_back(val);
        vecMutex.unlock();
    }
    size_t safeGetSize()
    {
        vecMutex.lock();
        size_t size = vec.size();
        vecMutex.unlock();
        return size;
    }
private:
    std::vector<int> vec;
    std::mutex vecMutex;
};

class safeStream
{
public:
    safeStream(){}
    ~safeStream(){}
    void Test()
    {
        std::thread t(&safeStream::tMonitorVec, this); // spawned a new thread
        for (size_t i = 0; i < 100; i++)
        {
            myVec.safePushBack(1);
            Sleep(10);
        }
        stopMonitoringMutex.lock();
        stopMonitoring = true;
        stopMonitoringMutex.unlock();
    }

private:
    void tMonitorVec()
    {
        stopMonitoring = false;
        size_t tempSize = myVec.safeGetSize();
        int count = 0;
        stopMonitoringMutex.lock();
        while (1)
        {
            if (stopMonitoring)
            {
                stopMonitoringMutex.unlock();
                break;
            }
            else
            {
                stopMonitoringMutex.unlock();
                if (tempSize != myVec.safeGetSize())
                {
                    count++;
                }
            }
        }
        std::cout << count;
    }
    SafeVec myVec;
    bool stopMonitoring;
    std::mutex stopMonitoringMutex;
};

int main()
{
    safeStream myStream;
    myStream.Test();

    return 0;
}
  • 0
    Может ли это быть из-за того, что оба потока одновременно получают vec типа safeVec? Но не должен ли мьютекс внутри safeVec позаботиться о конфликте в этом случае.
  • 0
    Предполагается, что Mutex правильно обрабатывает эти случаи (получая одновременно несколько потоков), поэтому это для :)
Показать ещё 8 комментариев
Теги:
multithreading
c++11
thread-safety
mutex

1 ответ

3
Лучший ответ

Это происходит в вашем цикле:

while (1)
{
    if (stopMonitoring)
    {
        stopMonitoringMutex.unlock();
        break;
    }
    else
    {
        // Whoops! I am here again !
        stopMonitoringMutex.unlock();
        if (tempSize != myVec.safeGetSize())
        {
            count++;
        }
    }
}

Еще одна вещь, которую следует учитывать: если вы используете std::mutex только для защиты одновременного доступа к field bool stopMonitoring; использовать std::atomic<bool> stopMonitoring; вместо этого, и забыть о мьютексах.

  • 0
    Да. Move stopMonitoringMutex.lock(); внутри while , потому что stopMonitoringMutex.unlock(); вызывается в каждом в while итерации.
  • 0
    Ооо, я вижу. Дай мне попробовать снова.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню