Векторные push_backs, выполненные в нескольких потоках (в течение 20 секунд), не показывают правильный размер вектора после wait_until (20 секунд) в первом потоке

#c #multithreading #vector #wait

#c #многопоточность #вектор #подождите

Вопрос:

Основываясь на примере boost chat и примере wait_until, я пытаюсь реализовать добавление сообщений в вектор (общий объект) при вызове конструктора, и размер вектора должен быть указан после ожидания в 20 секунд.

Что происходит ниже, когда в течение 20 секунд выполняются 2 вызова CreateBlock, так это то, что первый вызов CreateBlock ожидает 20 секунд, а затем размер вектора равен 1, затем есть еще одно ожидание в течение 20 секунд, также с размером вектора 1.

Вызов CreateBlock на сервере, вызываемый асинхронно от 2 разных клиентов:

 CreateBlock cb(message_j);
 

Класс:

 #include <condition_variable>
#include <thread>
#include <chrono>
#include <vector>
#include "json.hpp"

class CreateBlock
{
public:
    CreateBlock(nlohmann::json amp;message_j)
    {
        std::thread th (amp;CreateBlock::waits, this, std::ref(message_j));
        th.join();
    }
private:
    void waits(nlohmann::json amp;message_j)
    {
        {
            std::lock_guard<std::mutex> guard(cv_m);
            message_j_vec_.push_back(message_j);
            std::cout << "message_j_vec_.size(): " << message_j_vec_.size() << std::endl; // = 1
        }

        std::unique_lock<std::mutex> lk(cv_m);
        if(cv.wait_for(lk, 20s, [=]{return i == 1;})) 
        {
            std::cerr << "Thread finished waiting. i == " << i << 'n';
        }
        else
        {
            std::cerr << "Thread timed out. i == " << i << 'n';
            
            std::cout << "message_j_vec_.size(): " << message_j_vec_.size() << std::endl; // = 1
        }
    }
private:
    std::vector<nlohmann::json> message_j_vec_;

    std::condition_variable cv;
    std::mutex cv_m;
    int i;
};
 

Я пытался сделать вектор статическим, поместить вектор в отдельный класс,
сделал CreateBlock* cb = new CreateBlock(message_j), попытался поместить push_back в конструктор и создание потока другим методом, …
но ни один из этих экспериментов не привел к желаемому результату.

Есть идеи о том, как правильно решить эту проблему?

Tia.

Комментарии:

1. Конструктор не возвращается до тех пор, пока созданный им поток не завершится.

2. создание потока и немедленное присоединение к нему редко бывает правильным решением.

3. Является ли помещение векторного push_back в конструктор и создание потока в другом методе решением?

Ответ №1:

Ну, на самом деле здесь не было никакого ответа, так что я знал, что должен взглянуть на проблему иначе, чем я показал здесь. Итак, я изучил предыдущий шаг кода и затем работал над решением со статической переменной. Наконец мне удалось получить правильный размер в том месте, где я этого хотел.

Спасибо, что указали мне правильное направление, сохраняя молчание! Не обычный способ, но он работал. Тем не менее, мне потребовалась хорошая неделя!!