Member 12899279 Ответов: 2

Как автоматически запланировать поток, а затем остановить его от основного


в c++ main я хочу отправить start a thread в начале программы
этот поток должен вызывать функцию снова и снова до тех пор, пока не будет достигнут конец программы s, Что означает, что когда все остальное будет сделано, этот поток должен быть остановлен только тогда.
мне нужен этот поток, чтобы вызвать функцию рекурсивно, потому что мне нужно сделать что-то внутри этой функции через определенное время, скажем, через каждые 2 минуты я хочу, чтобы эта функция выполнялась сама собой, в то время как другие функции в main завершаются последовательно.после того, как каждая функция завершается последовательно, я хочу, чтобы поток остановился, и я не могу получить никакой логики, чтобы сделать это ниже мой код я не могу остановить поток с помощью std::terminate()
я думаю, что проблема заключается в бесконечном цикле, в котором функция вызывает себя рекурсивно
я не могу придумать никакой логики, чтобы сделать это

Что я уже пробовал:

#include<iostream>
#include<chrono>
#include<thread>
#include<functional>
//#include<unistd.h>
#include<Windows.h>
using namespace std;

void do_something()
{
	cout << "\ni am running after 1 minute in thread" << endl;
	int sleep_time = 1000;
	while (true)
	{
		Sleep(sleep_time);
		do_something();
	}
}
void simpleFunc()
{
	cout << "\nsimple function to check";
}
int main()
{
	cout << "\nIn main";
	//thread t1(timer_start(do_something()), 1);
	//while (true);
	thread th1(do_something);
	simpleFunc();
	cout << "\nafter the thread in main";
	Sleep(6000);
	cout << "\nafter Sleep in main";
	//th1.detach();
	//th1.detach();
	//th1.join();
	std::terminate();
	return 0;
	//std::terminate();
	//system("pause");
	//return 0;
}

Richard MacCutchan

Этот поток будет работать рекурсивно вечно; чего именно вы пытаетесь достичь с помощью этого кода?

Member 12899279

я знаю но внутри этой функции есть что то что мне нужно запустить через заданный интервал времени скажем 5 минут
мне нужно, чтобы эта функция вызывала себя снова и снова через 5 минут, поэтому я выделил для нее отдельный поток, потому что я хочу, чтобы она работала отдельно от другого последовательного кода в моем основном коде()
мне нужно чтобы этот поток остановился и одновременно эта функция тоже не выполнялась как только весь другой последовательный код будет закончен выполнение в main и в main я возвращаюсь 0

Richard MacCutchan

Вам нужно убить поток из main или использовать флаг, который main устанавливает, чтобы указать, что поток должен завершиться.

2 Ответов

Рейтинг:
2

Member 12899279

это было очень просто и легко я не знаю почему эта мысль не пришла мне в голову просто использовать флаг bool я думаю что я слишком много думал над очень простой задачей во всяком случае ниже приведен код

using namespace std;
bool stop_thread_1 = false;

void do_something(/*int i*/)
{
	int sleep_time = 1000;

	/*int count = i*/;
	while (stop_thread_1==false)
	{
		cout << "\ni am running after 1 minute in thread" << endl;

		Sleep(sleep_time);
	
	}
}
void simpleFunc()
{
	cout << "\nsimple function to check";
}
int main()
{
	cout << "\nIn main";
	thread th1(do_something);
	simpleFunc();
	cout << "\nafter the thread in main";
	Sleep(6000);
	cout << "\nafter Sleep in main";

	stop_thread_1 = true;
	th1.join();
	
	system("pause");
	exit(0);
	
}


Рейтинг:
2

CPallini

Я полагаю, вы можете изменить свой подход, избегая рекурсии. Следующая программа

#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
using namespace std;
using namespace std::chrono_literals;

void do_something()
{
  cout << "do something..." << endl;
}

void control_thread(std::atomic<bool> & stop)
{
  while (!stop)
  {
    this_thread::sleep_for(1s);
    do_something();
  }
}

int main()
{
  std::atomic<bool> stop{false};

  thread ct(control_thread, ref(stop));

  for (size_t n = 0; n<10; ++n)
  {
    cout << "main thread, iteration " << n << ", sleeping..." << endl;;
    this_thread::sleep_for(2.5s);
  }

  stop = true;
  cout << "wating for the thread to join..." << endl;
  ct.join();

  cout << "finished" << endl;
}

производит
main thread, iteration 0, sleeping...
do something...
do something...
main thread, iteration 1, sleeping...
do something...
do something...
main thread, iteration 2, sleeping...
do something...
do something...
do something...
main thread, iteration 3, sleeping...
do something...
do something...
main thread, iteration 4, sleeping...
do something...
do something...
do something...
main thread, iteration 5, sleeping...
do something...
do something...
main thread, iteration 6, sleeping...
do something...
do something...
do something...
main thread, iteration 7, sleeping...
do something...
do something...
main thread, iteration 8, sleeping...
do something...
do something...
do something...
main thread, iteration 9, sleeping...
do something...
do something...
wating for the thread to join...
do something...
finished


Member 12899279

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

CPallini

Мой, конечно, потому что он работает :-D
С серьезной стороны, рекурсия здесь плоха.

Member 12899279

нет вы не поняли мою точку зрения непосредственно перед вашим решением я опубликовал свое выше и в этом я больше не использую рекурсию

CPallini

Ваше решение настолько прекрасно, насколько оно соответствует вашим требованиям (возможно, я неправильно понял такие требования).

Member 12899279

у меня есть еще один вопрос, Что произойдет, если в main()была какая-то ошибка или исключение, которое привело к тому, что он не достиг конца main и вышел с исключением, что происходит с потоком тогда, потому что остановка потока зависит от значения bool, которое находится чуть выше возврата 0.
что делать, если никогда не достигнет этого значения bool?будет ли он работать вечно, пока компьютер не перезагрузится?

CPallini

Когда основной поток завершается, ОС удаляет весь процесс (поэтому вторичные потоки завершаются).

Member 12899279

включает ли это main, который был сломан, и его исключение не было обработано программистом, то есть он не использовал никакой try catch, чтобы поймать возможное исключение?

CPallini

Да, необработанные исключения приводят к завершению программы.

Member 12899279

ладно спасибо я просто боялся что он останется в памяти как демон до перезапуска