Home > front end >  Multithreaded console app on C is hanging
Multithreaded console app on C is hanging

Time:01-18

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.

enter image description here

  •  Tags:  
  • Related