How to stop a thread that runs active always?
Sep 19, 2020 at 2:00pm Sep 19, 2020 at 2:00pm UTC
Hi,
I have trouble with the following code. I want to create a thread that runs always. I want to stop it only when a variable changes from true to false. When I terminate the programm (Ctrl+C) main thread exits but second thread continues to run until I press again Ctrl+C.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#include <csignal>
#include <unistd.h>
#include <iostream>
#include <mutex>
#include <thread>
#include <atomic>
std::atomic_bool run(true );
void waitForSignals(sigset_t& signalSet);
void registerSignals(sigset_t& signalSet);
void signalHandler(int sig);
int main(int argc, char **argv) {
auto f1 = [&](){
while (run.load(std::memory_order_acquire))
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "TH ID " << std::this_thread::get_id() << " run: " << run.load() << std::endl;
}
};
std::thread th1(f1);
sigset_t signalSet;
registerSignals(signalSet);
waitForSignals(signalSet);
std::cout << "\n\nExiting...\n\n" << std::endl;
if (th1.joinable()) {
th1.join();
}
exit(0);
}
void signalHandler(int sig) {
run.store(false , std::memory_order_release);
std::cout << "signal run: " << run << std::endl;
}
void registerSignals(sigset_t& signalSet) {
signal(SIGTERM, signalHandler);
signal(SIGINT, signalHandler);
sigemptyset(&signalSet);
sigaddset(&signalSet, SIGINT);
sigaddset(&signalSet, SIGTERM);
}
void waitForSignals(sigset_t& signalSet) {
int exitSignal;
sigwait(&signalSet, &exitSignal);
}
Sep 19, 2020 at 7:38pm Sep 19, 2020 at 7:38pm UTC
idk, i can't even get the example you have posted here to compile. From what i've gathered im not entirely sure that ctr + c has anything to do with the signal library. Also what you have posted seems ridiculously complicated for just trying to manage a thread. This is what i got to work.... Idk. Good luck.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#include <Windows.h>
#include <csignal>
#include <iostream>
#include <thread>
#include <atomic>
std::atomic_bool run(true );
using namespace std;
bool WINAPI CtrlHandler(DWORD fdwCtrlType)
{
switch (fdwCtrlType)
{
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
run = false ;
return TRUE;
}
return false ;
}
int main() {
SetConsoleCtrlHandler(PHANDLER_ROUTINE(CtrlHandler), TRUE);
auto f1 = []() {
while (run)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "TH ID " << std::this_thread::get_id() << " run: " << run.load() << std::endl;
}
};
std::thread th1(f1);
while (run){}
cout << "exiting..." ;
if (th1.joinable()) {
th1.join();
}
}
Sep 19, 2020 at 9:30pm Sep 19, 2020 at 9:30pm UTC
Ok, I found the solution.
I am using Linux and trying to run it on Linux.
So, I don't know the exact problem but I should not do anything in signal handler. I should just wait for a signal. After that I can flip the flags. Here is the working example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#include <csignal>
#include <unistd.h>
#include <iostream>
#include <mutex>
#include <thread>
#include <atomic>
std::atomic_bool run(true );
void waitForSignals(sigset_t& signalSet);
void registerSignals(sigset_t& signalSet);
void signalHandler(int sig);
int main(int argc, char **argv) {
auto f1 = [&](){
while (run.load(std::memory_order_acquire))
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "TH ID " << std::this_thread::get_id() << " run: " << run.load() << std::endl;
}
};
std::thread th1(f1);
sigset_t signalSet;
registerSignals(signalSet);
waitForSignals(signalSet);
run.store(false , std::memory_order_release);
std::cout << "\n\nExiting...\n\n" << std::endl;
if (th1.joinable()) {
th1.join();
}
exit(0);
}
void signalHandler(int sig) {
}
void registerSignals(sigset_t& signalSet) {
signal(SIGTERM, signalHandler);
signal(SIGINT, signalHandler);
sigemptyset(&signalSet);
sigaddset(&signalSet, SIGINT);
sigaddset(&signalSet, SIGTERM);
}
void waitForSignals(sigset_t& signalSet) {
int exitSignal;
sigwait(&signalSet, &exitSignal);
}
Topic archived. No new replies allowed.