Как правильно создать потоки в C++?

Мне понадобилось создать 2 потока, которые выполняют разные функции, вот пример:

#include <iostream>
#include <thread>
using namespace std;

int one() {
   for(int i=0; i<5; i++){
    cout << "from thread 1" << endl;
   }
    return 0;
}

int two(){
    for(int i=0; i<5; i++){
    cout<<"from thread 2" << endl;
}
    }

int main() {
     new thread(one);
     new thread(two);
   return 0;
}

Но вместо создания потоков у меня появляется огромный блок ошибок - https://pastebin.com/raw/wreRKfFR

Могу предположить, что я либо неправильно запускаю потоки, либо их надо как-то завершить. Помогите, пожалуйста.


Ответы (2 шт):

Автор решения: eri

Минимум нужно дождаться потоков перед завершением main().

#include <iostream>
#include <thread>
using namespace std;

int one() {
   for(int i=0; i<5; i++){
    cout << "from thread 1" << endl;
   }
    return 0;
}

int two(){
    for(int i=0; i<5; i++){
    cout<<"from thread 2" << endl;
}
    }

int main() {
   thread t1(one);
   thread t2(two);
   t1.join()
   t2.join()
   return 0;
}
→ Ссылка
Автор решения: Maggot

Ну для удобства лучше не просто создавать std::thread - а обернуть вызываемый метод(функцию) в std::packaged_task что позволит просто получить занчение или отловить exception

вот пример

#include <iostream>
#include <thread> 
#include <future>

int Task_1(int& val) {
  std::cout << "Thread_id : " << std::this_thread::get_id() << std::endl;
  return ++val;
}

int main() {
  std::packaged_task<int(int&)> xTask{Task_1};
  auto task = xTask.get_future();
  std::thread th_1;
  int start_val{777};
  
  if (!th_1.joinable()) {
    th_1 = std::thread(std::move(xTask), std::ref(start_val));
  } else {
    th_1.join();
     th_1 = std::thread(std::move(xTask), std::ref(start_val));
  }
  try {
    th_1.join();
     task.wait();
     auto ret{task.get()};
    std::cout << "Ret from thread : " << ret << " start_val : " << start_val << std::endl;
  } catch (std::exception& exc) {
    std::cout << "Catch Exception! msg is : " << exc.what() << std::endl;
  } catch (...) {
    std::cout << "unknown error ~ !"<< std::endl;
  }
    
  return 0; 
}

Ну а для 2-х задач

#include <iostream>
#include <thread> 
#include <future>

int Task_1(int& val) {
  std::cout << "Thread_id : " << std::this_thread::get_id() << "; Val : " << val << std::endl;
  return ++val;
}

int main() {
  std::packaged_task<int(int&)> xTask{Task_1}, xTask2{Task_1};
  auto task = xTask.get_future();
  auto task2 = xTask2.get_future();
  std::thread th_1, th_2;
  int start_val{777};
  int start_val_t2{999};
  
  if (!th_1.joinable()) {
    th_1 = std::thread(std::move(xTask), std::ref(start_val));
  } else {
    th_1.join();
     th_1 = std::thread(std::move(xTask), std::ref(start_val));
  }

  if (!th_2.joinable()) {
    th_2 = std::thread(std::move(xTask2), std::ref(start_val_t2));
  } else {
    th_2.join();
     th_2 = std::thread(std::move(xTask2), std::ref(start_val_t2));
  }

  try {
    th_1.join();
     task.wait();
     auto ret{task.get()};
    std::cout << "Ret from thread : " << ret << " start_val : " << start_val << std::endl;
  } catch (std::exception& exc) {
    std::cout << "Catch Exception! msg is : " << exc.what() << std::endl;
  } catch (...) {
    std::cout << "unknown error ~ !"<< std::endl;
  }

   try {
    th_2.join();
     task2.wait();
     auto ret{task2.get()};
    std::cout << "Ret from thread : " << ret << " start_val : " << start_val_t2 << std::endl;
  } catch (std::exception& exc) {
    std::cout << "Catch Exception! msg is : " << exc.what() << std::endl;
  } catch (...) {
    std::cout << "unknown error ~ !"<< std::endl;
  }
    
  return 0; 
}
→ Ссылка