Современный C ++. Вернуть структуру данных из рабочего потока, продолжая его выполнение

Как уже говорили другие, vector внутренне использует непрерывный массив объектов. Указатели в этот массив должны рассматриваться как недействительные, когда любая неконстантная функция-член называется IIRC.

Однако существует исключение !!

vector<bool> имеет специализированную реализацию, разработанную для экономии места, так что каждый bool использует только один бит. Базовый массив не является смежным массивом арифметики bool и массива на vector<bool> не работает, как vector<T>.

(я полагаю, также возможно, что это может быть справедливо для любой специализации вектора , так как мы всегда можем реализовать новую. Однако std::vector<bool> является единственной, ошибочной, стандартной специализацией, на которой простая арифметика указателя не будет работать.)

0
задан Alex_A 18 January 2019 в 02:30
поделиться

1 ответ

Попробуйте использовать указатель или ссылку на структуру данных с ответом в нем, и std :: condition_variable, чтобы сообщить вам, когда ответ был вычислен:

#include <iostream>           
#include <thread>             
#include <mutex>              
#include <condition_variable> 

#include <chrono>
#include <vector>

std::vector<double> g_my_answer;
std::mutex g_mtx;
std::condition_variable g_cv;
bool g_ready = false;


void Worker_treadfun_with_init()
{
  //Do your initialization here
  {
     std::unique_lock<std::mutex> lck( g_mtx );
     for( double val = 0; val < 10; val += 0.3 )
       g_my_answer.push_back( val );

     g_ready = true;
     lck.unlock();
     g_cv.notify_one();
  }

  //Keep doing your other work..., here we'll just sleep
  for( int i = 0; i < 100; ++i )
  {
    std::this_thread::sleep_for( std::chrono::seconds(1) );
  }
}

void Caller()  
{
  std::unique_lock<std::mutex> lck(g_mtx);

  std::thread worker_thread = std::thread( Worker_treadfun_with_init );

  //Calling wait will cause current thread to sleep until g_cv.notify_one() is called.
  g_cv.wait( lck, [&g_ready](){ return g_ready; } ); 

  //Print out the answer as the worker thread continues doing its work
  for( auto val : g_my_answer )
    std::cout << val << std::endl;

  //Unlock mutex (or better yet have unique_lock go out of scope)
  // incase worker thread needs to lock again to finish
  lck.unlock();  

  //...

  //Make sure to join the worker thread some time later on.
  worker_thread.join();
}

Конечно, в реальном коде вы не использовал бы глобальные переменные, а вместо этого передавал бы их по указателю или по ссылке (или как переменные-члены SomeClass) в рабочую функцию, но вы понимаете, в чем дело.

0
ответ дан wcjohns 18 January 2019 в 02:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: