Сделаю.

чаю многопоточность и написал этот код:

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

int distance = 20;
int distanceCovered = 0;
std::condition_variable cv;
std::mutex mu;

void keep_moving(){
  while(true){
  std::cout << "Distance is: " << distanceCovered << std::endl;
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  distanceCovered++;
  if(distanceCovered == distance){
    cv.notify_one();
    std::terminate();
   }
 }
}

void wake_me_up()
{
  std::unique_lock<std::mutex> ul(mu);
  cv.wait( ul, []{ return distanceCovered==distance; });   // protects the lines of code below
  std::cout << "I'm here" << std::endl;
  std::terminate();
}

int main() {
  std::thread driver(keep_moving);
  std::thread wake_me(wake_me_up);
  driver.join();
  wake_me.join();

  system("pause");

  return 0;
}

Как вы можете видеть, поток keep_moving считает от 0 до 20 в течение 20 секунд, а затем уведомляет поток «wake_me_up», который печатает «Я здесь», а затем завершается. После уведомления потока «keep_moving» также завершается.

Пожалуйста, скажите мне, правильно ли я завершаю темы. Когда я запускаю этот код, я получаю следующее сообщение:

terminate called without an active exception
I'm here
terminate called recursively
Aborted

Спасибо.

 Rob K21 нояб. 2017 г., 16:19
Почему вы думаете, что должны звонитьstd::terminate? Потому что тыдействительно не должно быть
 Kennedy22 нояб. 2017 г., 11:59
Роб К, потому что моя программа насчитывает от 1 до 20, а затем я хотел, чтобы вторая нить напечатала «Я здесь», тогда все будет готово. Но вместо этого после этого thread1 продолжает увеличивать это значение с 20 до бесконечности. У меня сложилось впечатление, что после завершения функции main оба потока выходят за рамки :). Но, видимо, я не правильно понял это. Есть ли способ достичь того, чего я хочу, не делая ничего, что не рекомендуется?

Ответы на вопрос(1)

завершить поток - это возврат из его функции потока.

std::terminate убивает весь ваш процесс. Даже если он только убил текущий поток (т.е. вел себя как Win32TerminateThread функция,что вы должныникогда вызов!), он не размотает стек, не вызовет деструкторы и, таким образом, возможно, оставит некоторую необходимую очистку незавершенной (например, освобождение мьютексов).

std::terminate предназначен для использования при критическом сбое, когда ваша программа не может продолжаться. Сообщение «без активного исключения» происходит потому, что основное использованиеterminate убить программу в случае сбоя системы исключений, например, из-за вложенного исключения, поэтому функция по умолчанию ищет активное исключение и печатает информацию о нем.

 Sebastian Redl21 нояб. 2017 г., 16:35
@AndyG Нет, не можешь. [terminate.handler] говорит: «Обязательное поведение: terminate_handler должен прекратить выполнение программы без возврата к вызывающей стороне». Если ваш обработчик завершения не убивает вашу программу, ваша программа имеет неопределенное поведение.
 Sebastian Redl22 нояб. 2017 г., 10:14
Только чтоreturn; Сделаю.
 AndyG21 нояб. 2017 г., 16:53
@SebastianRedl: Спасибо за исправление!
 Passer By21 нояб. 2017 г., 16:36
Но не могли бы вы сделать что-то в обработчике завершения?
 Sebastian Redl21 нояб. 2017 г., 16:40
@PasserBy Да. Вы можете делать вещи. И тогда вы должны как-то остановить выполнение процесса. Вы можете позвонитьstd::abort или жеExitProcess или дажеexec если вы хотите, но процесс не должен продолжаться. Что ж, если вы работаете в системе без процессов, вы можете решить ввести бесконечный цикл «мигающий предупреждающий светодиод».

Ваш ответ на вопрос