пытаясь понять переменные состояния - PullRequest
1 голос
/ 08 мая 2020

Я читал о переменных состояния для передачи сигналов между двумя или более потоками. Теперь я пытаюсь понять какой-то код, который у меня есть. У меня есть (упрощено):

class Class{
    void put(Something&& something){
        {
            std::lock_guard<std::mutex> lock(a_mutex);
            // Do the operation here
            some_operation();
        }
        cond_var.notify_one();
    }
    
    std::unique_ptr<Something> get(){
        std::unique_lock<std::mutex> lock(a_mutex);
   
        cond_var.wait(lock,[this]{return someCondition()});
    
        //Do the operation here
        auto res=some_other_operation();
        return res;
    }
    
    std::mutex a_mutex;
    std::condition_variable cond_var;    
};

Я понимаю, что put получает блокировку и выполняет некоторую операцию, а затем уведомляет любой поток, ожидающий разблокировки. Также get блокируется до тех пор, пока условная переменная не будет сигнализирована оператором put, или блокируется, если someCondition не истинно. После получения сигнала он выполняет другую операцию и возвращает свое значение.

Чего я не понимаю, так это времени.

Например, предположим, что вызывается функция put и она уведомляет, но ни один поток не ожидает, потому что get не был вызван. Что происходит?

Затем, допустим, вызывается get и блокируется. Или нет? (в идеале это не должно , потому что кто-то уже позвонил put первым).

Следует get подождать, пока put не будет вызван снова ?

1 Ответ

2 голосов
/ 08 мая 2020

Например, предположим, что функция put вызывается, и она уведомляет, но ни один поток не ожидает, потому что get не был вызван. Что происходит?

в документах говорится: * Если какие-либо потоки ожидают this, вызов notify_one разблокирует один из ожидающих потоков. Если есть , то если ничего особенного не происходит.

Затем, допустим, вызывается get и блокируется. Или нет ?? (в идеале этого не должно быть, потому что кто-то уже позвонил первым).

Он будет условно заблокирован до someCondition(). Если someOperation() приводит к реализации someCondition(), то wait будет разблокирован при вызове notify_one() или не заблокирован вообще, если someCondition() уже реализован.

...