I wrote multithreaded console program to parallel calculation. Program is running from PowerShell. In general it work well: main thread, thread for output and 7 work threads (for 8 logical cores), CPU usage is 85%. But sometimes, for example when I am using laptop for some outher tasks: web-surfing, simple work in MS Word, e.t.c, all thread are stopping, CPU usage is 0%. If I press Ctrl C, there is output results of finished threads and program work continuous normally.
all threads are created and stopped in same time:
Started: k = 1 N/mm, dzeta = 0.01
Started: k = 1 N/mm, dzeta = 0.1
Started: k = 1 N/mm, dzeta = 0.2
Started: k = 1 N/mm, dzeta = 0.5
Started: k = 1 N/mm, dzeta = 0.7
Started: k = 1 N/mm, dzeta = 1
Started: k = 2 N/mm, dzeta = 0.01
Started: k = 2 N/mm, dzeta = 0.1
Finished: k = 1 N/mm, dzeta = 0.1, Last n_rot 29.2 krpm.
Finished: k = 1 N/mm, dzeta = 0.01, Last n_rot 29.6 krpm.
Finished: k = 1 N/mm, dzeta = 0.2, Last n_rot 29.4 krpm.
Finished: k = 2 N/mm, dzeta = 0.01, Last n_rot 29.7 krpm.
Finished: k = 1 N/mm, dzeta = 0.7, Last n_rot 29.5 krpm.
Finished: k = 1 N/mm, dzeta = 1, Last n_rot 29.6 krpm.
Finished: k = 1 N/mm, dzeta = 0.5, Last n_rot 29.4 krpm.
Started: k = 2 N/mm, dzeta = 0.2
Started: k = 2 N/mm, dzeta = 0.5
Started: k = 2 N/mm, dzeta = 0.7
Started: k = 2 N/mm, dzeta = 1
Started: k = 3 N/mm, dzeta = 0.01
Started: k = 3 N/mm, dzeta = 0.1
Started: k = 3 N/mm, dzeta = 0.2
normal work
Started: k = 3 N/mm, dzeta = 0.2
Finished: k = 2 N/mm, dzeta = 0.2, Last n_rot 29.4 krpm.
Started: k = 3 N/mm, dzeta = 0.5
Finished: k = 2 N/mm, dzeta = 1, Last n_rot 29.6 krpm.
Started: k = 3 N/mm, dzeta = 0.7
Finished: k = 2 N/mm, dzeta = 0.5, Last n_rot 29.5 krpm.
Started: k = 3 N/mm, dzeta = 1
Finished: k = 2 N/mm, dzeta = 0.7, Last n_rot 29.6 krpm.
Started: k = 4 N/mm, dzeta = 0.01
Finished: k = 3 N/mm, dzeta = 0.01, Last n_rot 29.9 krpm.
Started: k = 4 N/mm, dzeta = 0.1
Finished: k = 2 N/mm, dzeta = 0.1, Last n_rot 29.3 krpm.
Started: k = 4 N/mm, dzeta = 0.2
Finished: k = 3 N/mm, dzeta = 0.1, Last n_rot 29.4 krpm.
Started: k = 4 N/mm, dzeta = 0.5
Finished: k = 3 N/mm, dzeta = 0.2, Last n_rot 29.4 krpm.
Started: k = 4 N/mm, dzeta = 0.7
Finished: k = 3 N/mm, dzeta = 0.5, Last n_rot 29.6 krpm.
Started: k = 4 N/mm, dzeta = 1
Finished: k = 3 N/mm, dzeta = 1, Last n_rot 29.7 krpm.
Will be glad to get any idea why it is freezing!
main thread
std::list<Answer> results;
AnswersContainerClass AnswersContainer;
int Max_Number_Threads = std::thread::hardware_concurrency() - 1;
std::atomic<int> Threads_counter = 0;
std::atomic<bool> end_flag = false;
std::future<bool> results_are_out = std::async(std::launch::async, multithread_results_output, &results, &AnswersContainer, &end_flag, &dzeta_test, &k_tests);
boost::posix_time::ptime begin_time(boost::posix_time::second_clock::local_time());
for (unsigned int i = N_k_first; i < N_k_last; i ) {
for (unsigned int j = N_dzeta_first; j < N_dzeta_last; j )
{
PointHousingEquationSystem *ODE_copy = new PointHousingEquationSystem(ODE);
std::unique_ptr<StiffIntegratorT> stiffT = std::make_unique<StiffIntegratorT>(ODE_copy, ODE_copy->GetND(), y, x_begin, x_end);
stiffT->SetMaxStepSize(max_step_size);
stiffT->SetMaxNumberOfSteps(200'000);
ODE_copy->System->Bearing.set_dzeta_corp(dzeta_test[j]);
ODE_copy->System->Bearing.set_k_corp_bearing(k_tests[i]);
if (cout_flag)
{
stdcout_mutex.lock();
std::cout << "Started: k = " << std::setw(5) << k_tests[i] / 1000. << " N/mm, " << "dzeta = " << std::setprecision(3) << dzeta_test[j] << std::endl;
stdcout_mutex.unlock();
}
while (Threads_counter >= Max_Number_Threads)
std::this_thread::sleep_for(1000ms);
AnswersContainer.flag.lock();
AnswersContainer.Answers.push(std::async(std::launch::async, Background_Solver, i, j, ODE_copy, move(stiffT), &Threads_counter));
AnswersContainer.flag.unlock();
Threads_counter ;
}
}
end_flag.store(true, std::memory_order::memory_order_relaxed);
results_are_out.get();
background_worker
Answer Background_Solver(unsigned int i, unsigned int j, PointHousingEquationSystem *ODE, std::unique_ptr<StiffIntegratorT> Integrator, std::atomic<int> *Threads_counter)
{
bool showed = false;
try
{
Integrator->Integrate();
}
catch (std::runtime_error &e)
{
stdcout_mutex.lock();
std::cout << "Finished: k = " << std::setw(5) << ODE->System->Bearing.get_k_corp_bearing() / 1000. << " N/mm, " << "dzeta = " << std::setprecision(3)
<< ODE->System->Bearing.get_dzeta_corp() << ", Last n_rot " << ODE->System->Point.get_rotation_frequancy() << " krpm." << std::endl;
stdcout_mutex.unlock();
showed = true;
}
catch (...)
{
stdcout_mutex.lock();
std::cout << "Caught an unknown exception" << std::endl;
stdcout_mutex.unlock();
(*Threads_counter)--;
delete ODE;
return Answer(i, j, -1.0);
}
if (!showed) {
stdcout_mutex.lock();
std::cout << "Finished: k = " << std::setw(5) << ODE->System->Bearing.get_k_corp_bearing() / 1000. << " N/mm, " << "dzeta = " << std::setprecision(3)
<< ODE->System->Bearing.get_dzeta_corp() << ", Last n_rot " << ODE->System->Point.get_rotation_frequancy() << " krpm." << std::endl;
stdcout_mutex.unlock();
}
(*Threads_counter)--;
double rotation_frequancy = ODE->System->Point.get_rotation_frequancy();
delete ODE;
return Answer(i, j, rotation_frequancy);
}
multithread_output
bool multithread_results_output(std::list<Answer> *results, AnswersContainerClass *Answers, std::atomic<bool> *end_flag,
std::vector<double> *dzeta_test, std::vector<double> *k_tests)
{
std::ofstream output_file;
output_file.open(output_filename);
std::this_thread::sleep_for(1000ms);
while (!(*end_flag) || !(Answers->Answers.empty()))
{
Answer ans = Answers->Answers.front().get();
results->push_back(ans);
if (ans.j == 0)
{
output_file << (*k_tests)[ans.i] << " " << ans.omega << " ";
}
else
{
if (ans.j < (N_dzeta_last - 1))
output_file << ans.omega << " ";
else
output_file << ans.omega << std::endl;
}
Answers->flag.lock();
Answers->Answers.pop();
Answers->flag.unlock();
std::this_thread::sleep_for(1000ms);
}
output_file.close();
return true;
}
CodePudding user response:
Raymond Chen, was right! If I click in the PowerShell
and trigger text selection (see picture), program stacked on std::cout
and seems freezed. After Ctrl C, std::out
relesed and the process is continuous.
There is no such problem with Cygwin Bash
and I was not able to cath this problem with gdb
.