Suppose I have a future object to run a process, and then in my main function I check if the process is timed out, in which case I want to end the program.
Consider the following template code:
//(include relevant libraries)
int main() {
std::future<int> future = std::async(std::launch::async, []() {
int result = uncertainFunctionCall();
return result;
});
std::future_status status = future.wait_for(std::chrono::milliseconds(50));
if (status == std::future_status::timeout) {
std::cout << "Timeout" << std::endl;
exit();
}
try {
std::cout << future.get() << std::endl;
std::cout << "Success" << std::endl;
}
catch(...) {
std::cout << "Exception Occurred" << std::endl;
exit();
}
return 0;
}
My question is, should there circumstances under which I need to do some cleaning up before calling the exit() function? For my use case, I only care about getting the value, but I don't want uncertainFunctionCall() to affect future executions of this program.
Related
This question already has answers here:
How do I terminate a thread in C++11?
(7 answers)
How to stop the thread execution in C++
(3 answers)
Proper way to terminate a thread in c++
(1 answer)
Closed 3 years ago.
My main function loads a monitoring class. This class calls external services to periodically get some data and report health status.
These are the task_1 and task_2 in the class below, that can have sub tasks. The tasks accumulate some values that are stored to a shared "Data" class.
So each task_N is coupled with a thread that executes, sleeps for a while and does this forever until the program stops.
My basic problem is that I cannot stop the threads in the Monitor class, since they might be waiting for the timer to expire (sleep)
#include <iostream>
#include <thread>
#include <utility>
#include "Settings.hpp"
#include "Data.hpp"
class Monitors {
public:
Monitors(uint32_t timeout1, uint32_t timeout2, Settings settings, std::shared_ptr<Data> data)
: timeout_1(timeout1), timeout_2(timeout2), settings_(std::move(settings)), data_(std::move(data)) {}
void start() {
thread_1 = std::thread(&Monitors::task_1, this);
thread_2 = std::thread(&Monitors::task_2, this);
started_ = true;
}
void stop() {
started_ = false;
thread_1.join();
thread_2.join();
std::cout << "stopping threads" << std::endl;
}
virtual ~Monitors() {
std::cout << "Monitor stops" << std::endl;
}
private:
void subtask_1_1() {
//std::cout << "subtask_1_1 reads " << settings_.getWeb1() << std::endl;
}
void subtask_1_2() {
//std::cout << "subtask_1_2" << std::endl;
data_->setValue1(21);
}
void task_1() {
while(started_) {
subtask_1_1();
subtask_1_2();
std::this_thread::sleep_for(std::chrono::milliseconds(timeout_1));
std::cout << "task1 done" << std::endl;
}
}
void subtask_2_1() {
//std::cout << "subtask_2_1" << std::endl;
}
void subtask_2_2() {
//std::cout << "subtask_2_2" << std::endl;
}
void task_2() {
while(started_) {
subtask_2_1();
subtask_2_2();
std::this_thread::sleep_for(std::chrono::milliseconds(timeout_2));
std::cout << "task2 done" << std::endl;
}
}
private:
bool started_ {false};
std::thread thread_1;
std::thread thread_2;
uint32_t timeout_1;
uint32_t timeout_2;
Settings settings_;
std::shared_ptr<Data> data_;
};
The main function is here:
auto data = std::make_shared<Data>(10,20);
Settings set("hello", "world");
Monitors mon(1000, 24000,set,data);
mon.start();
int count = 1;
while(true) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << data->getValue2() << " and count is " << count << std::endl;
count++;
if ( count == 10)
break;
}
std::cout << "now I am here" << std::endl;
mon.stop();
return 0;
Now when I call mon.stop() the main thread stops only when the timer exprires.
How can I gracefully call mon.stop() and interrupt and call the task_N?
UPDATE: Since I don't want to call std::terminate, which is the proper way to implement a monitor class in c++
Let's say we have two running threads that both would throw exceptions and there are exception handlers in these threads.
Would C++ be able to handle that, not running into terminated or undefined behavior.
Is it correct that exception belongs to per thread, and each thread can have no more than one exception at a time?
Is it correct that exception belongs to per thread
That is correct.
and each thread can have no more than one exception at a time?
A thread can have more than one active exception. See int uncaught_exceptions() noexcept:
Detects how many exceptions in the current thread have been thrown or rethrown and not yet entered their matching catch clauses.
E.g.:
#include <iostream>
#include <stdexcept>
void f() {
throw std::runtime_error("error");
}
struct A {
~A() {
std::cout << "uncaught_exceptions: " << std::uncaught_exceptions() << '\n';
}
};
struct B {
~B() {
try {
A a;
f();
}
catch(std::exception&) {}
}
};
int main() {
try {
B b;
f();
}
catch(std::exception&) {}
}
Outputs:
uncaught_exceptions: 2
The following example shows that the exception handler is using the stack of thread t1 which made a division by zero exception. It means that exception belongs to per thread.
// g++ -std=c++0x -pthread -fnon-call-exceptions main.cpp
#include <iostream>
#include <thread>
#include <signal.h>
void handler(int signo) {
int handler_local_var;
std::cout << &handler_local_var << " in stack of handler" << std::endl;
throw signo;
}
void thread1(std::string msg) {
int t1_local_var;
std::cout << &t1_local_var << " in stack of " << msg << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
signal(SIGFPE,handler);
try {
int x = 100 / 0; /* ignore warning: division by zero [-Wdiv-by-zero] */
}
catch (...) {
std::cout << "caught" << std::endl;
}
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
void thread2(std::string msg) {
int t2_local_var;
std::cout << &t2_local_var << " in stack of " << msg << std::endl;
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
int main() {
int main_local_var;
std::cout << &main_local_var << " in stack of main" << std::endl;
std::thread t1(thread1,"t1");
std::thread t2(thread2,"t2");
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(2)); /* Ctrl-C to stop */
}
return 0;
}
Test result:
$ ./a.out
0x7ffee7fea788 in stack of main
0x7f0b54b92d68 in stack of t2
0x7f0b55393d54 in stack of t1
0x7f0b55393754 in stack of handler
caught
I am trying to run some function in asynchronous manner. For this purpose I wrote class called Core where I use std::async to run function in different thread and std::shared_future<int> to wait for this thread and possibly to get future result. This is code of test program:
#include <iostream>
#include <future>
class Core : public std::enable_shared_from_this<Core>
{
public:
Core()
: isRunning_(false) {
};
~Core() {
isRunning_ = false;
if (f_.valid())
{
f_.wait();
std::cout << "Result is: " << f_.get() << std::endl;
}
};
void Start() {
isRunning_ = true;
auto self(shared_from_this());
f_ = std::async(std::launch::async, [self, this]() {
try {
while (true) {
if (!isRunning_)
break;
std::cout << "Boom" << std::endl; // Error occurs here
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
catch (const std::exception& e) {
std::cerr << "Loop error:" << e.what();
}
return 999;
});
}
private:
std::shared_future<int> f_;
std::atomic<bool> isRunning_;
};
int main()
{
try {
std::shared_ptr<Core> load(new Core);
load->Start();
throw std::runtime_error("Generate error"); // Added in order to generate error
}
catch (const std::exception& e) {
std::cout << "Error occurred: " << e.what();
}
return 0;
}
Each time when I start this program it crashes at this line:
std::cout << "Boom" << std::endl; // Error occurs here
with this error:
That is debugger error and call stack which I managed to get during debugging:
Looks like Core destructor function doesn't call at all. Why is it happens? weird!!!
Could you tell me where is my mistake? Thanks.
When main thread returns from main() it starts tearing down the environment before terminating the whole process. All this while background thread is accessing objects there are being destroyed or have been destroyed already.
I am not sure what you are triying to achieve, but you are doing something wrong:
Your lambda should execute some work and return immediately after it is done e.g. you should never loop forever.
Your main thread should wait for your future to complete by calling std::future<T>::get().
Building a SignalR C++ client using Visual Studio 2013, I am starting with the working sample code from NuGet Package Microsoft.AspNet.SignalR.Client.Cpp.v120.WinDesktop, source here
Reviewing the library source it seems to me the event handling processes are based on the Concurrency Runtime (pplx::task) which relies on C++11 features
void chat(const utility::string_t& name)
{
signalr::hub_connection connection{ U("https://testsite") };
auto proxy = connection.create_hub_proxy(U("ChatHub"));
proxy.on(U("broadcastMessage"), [](const web::json::value& m)
{
ucout << std::endl << m.at(0).as_string() << U(" wrote:") << m.at(1).as_string() << std::endl << U("Enter your message: ");
});
connection.start()
.then([proxy, name]()
{
for (;;)
{
utility::string_t message;
std::getline(ucin, message);
if (message == U(":q"))
{
break;
}
send_message(proxy, name, message);
}
})
.then([&connection]() // fine to capture by reference - we are blocking so it is guaranteed to be valid
{
return connection.stop();
})
.then([](pplx::task<void> stop_task)
{
try
{
stop_task.get();
ucout << U("connection stopped successfully") << std::endl;
}
catch (const std::exception &e)
{
ucout << U("exception when starting or stopping connection: ") << e.what() << std::endl;
}
}).get();
}
I want to eliminate the "user input" component; and instead quit loop when a particular "broadcastMessage" has been received.
If I replace the for loop with a sleep statement, the broadcastMessage event stops firing.
If I use the for loop without the getline, set bComplete to true when done, it works the way I want but causes high CPU usage (obviously)
for (;;)
{
if (bComplete) break;
}
Ideally I want connection to start, and then just wait until the broadcastMessage events signals to close the connection.
In addition the "chat" function shouldn't return until connection has closed.
I can see in your answer that you've already discovered Windows event objects; however, if you were looking for a C++11 platform-independent solution, consider std::condition_variable!
unsigned int accountAmount;
std::mutex mx;
std::condition_variable cv;
void depositMoney()
{
// go to the bank etc...
// wait in line...
{
std::unique_lock<std::mutex> lock(mx);
std::cout << "Depositing money" << std::endl;
accountAmount += 5000;
}
// Notify others we're finished
cv.notify_all();
}
void withdrawMoney()
{
std::unique_lock<std::mutex> lock(mx);
// Wait until we know the money is there
cv.wait(lock);
std::cout << "Withdrawing money" << std::endl;
accountAmount -= 2000;
}
int main()
{
accountAmount = 0;
std::thread deposit(&depositMoney);
std::thread withdraw(&withdrawMoney);
deposit.join();
withdraw.join();
std::cout << "All transactions processed. Final amount: " << accountAmount << std::endl;
return 0;
}
In this example we make two threads: one to deposit money into the account and one to withdraw money. Because it's possible for the thread to withdraw the money to run first, especially because there's more processing involved with depositMoney(), we need to wait until we know the money is there. We lock our thread before accessing the money, and then tell the condition_variable what we are waiting for. The condition_variable will unlock the thread, and once the money has been deposited and notify_all() is called we'll be re-awoken to finish processing our logic.
Note that it's possible to do the exact same using the Windows event objects. Instead of std::condition_variable::wait() and std::condition_variable::notify_all() you'd use SetEvent() and WaitForSingleObject(). This is platform-independent though.
I got this working using WinAPI WaitForSingleObject:
HANDLE hEvent;
void chat(const utility::string_t& name)
{
signalr::hub_connection connection{ U("https://testsite") };
auto proxy = connection.create_hub_proxy(U("ChatHub"));
proxy.on(U("broadcastMessage"), [](const web::json::value& m)
{
ucout << std::endl << m.at(0).as_string() << U(" wrote:") << m.at(1).as_string() << std::endl;
if (m.at(1).as_string() == L"quit")
{
SetEvent(hEvent);
}
});
hEvent = CreateEvent(0, TRUE, FALSE, 0);
connection.start()
.then([proxy, name]()
{
WaitForSingleObject(hEvent, INFINITE);
})
.then([&connection]() // fine to capture by reference - we are blocking so it is guaranteed to be valid
{
return connection.stop();
})
.then([](pplx::task<void> stop_task)
{
try
{
stop_task.get();
ucout << U("connection stopped successfully") << std::endl;
}
catch (const std::exception &e)
{
ucout << U("exception when starting or stopping connection: ") << e.what() << std::endl;
}`enter code here`
}).get();
}
This question already has answers here:
How to get the winapi id of a thread that has been created using the standard library?
(2 answers)
Closed 7 years ago.
Could it be posible to cast or convert a std::thread thread in C++ to a HANDLE in Windows?
I've been trying to manage threads in Windows with WINAPI functions for threads but I can't get it to work...
#include <thread>
#include <string>
#include <iostream>
#include <windows.h>
void Hi(std::string n){
while(true){
std::cout<<"Hi :3 "<<n<<"\n";
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main(void){
std::thread first(Hi, "zoditu");
first.detach();
getc(stdin);
//SuspendThread((void*)first.native_handle());
TerminateThread((void*)first.native_handle(), (unsigned long)0x00);
CloseHandle((void*)first.native_handle());
std::cout<<"No D:!!\n";
getc(stdin);
return 0;
}
But seems to do nothing because thread keeps spawning "Hi's" in the console... Could there be a way to "kill" it using WINAPI?
I don't think there is anything wrong with using the value returned by std::thread::native_handle() directly with the Win32 API functions (i.e., a conversion is not required).
The following program works for me. However, it usually (always?) crashes if the thread is terminated while it is actively executing but works just fine if the thread is suspended before terminating. As you are aware and others have pointed out it is generally not a good idea to terminate a thread.
But to answer your question the Win32 API seems to work as expected without any additional conversions. The following program works for me.
Program:
#include <windows.h>
#include <iostream>
#include <string>
#include <thread>
void foo()
{
while (true)
{
std::cout << "foo()\n";
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main(void)
{
std::thread first(foo);
bool isFinished = false;
while (!isFinished)
{
char ch = ::getchar();
::getchar(); // Swallow the new line character
if (ch == 'e')
{
isFinished = true;
}
else if (ch == 's')
{
DWORD result = ::SuspendThread(first.native_handle());
if (result != -1)
{
std::cout << "Successfully suspended thread\n";
}
else
{
std::cout << "Failed to suspend thread: failure resson " << ::GetLastError() << "\n";
}
}
else if (ch == 'r')
{
DWORD result = ::ResumeThread(first.native_handle());
if (result != -1)
{
std::cout << "Successfully resumed thread\n";
}
else
{
std::cout << "Failed to resume thread: failure resson " << ::GetLastError() << "\n";
}
}
else if (ch == 'k')
{
DWORD result = ::TerminateThread(first.native_handle(), 1);
if (result != 0)
{
std::cout << "Successfully terminated thread\n";
}
else
{
std::cout << "Failed to terminate thread: failure resson " << ::GetLastError() << "\n";
}
}
else
{
std::cout << "Unhandled char '" << ch << "'\n";
}
}
first.detach();
std::cout << "waiting to exit main...";
::getchar();
std::cout << "exiting...\n";
return 0;
}
Sample Output (comments added by me):
foo()
foo()
foo()
foo()
s
Successfully suspended thread // This was successful since 'foo()' is no longer printing
r
Successfully resumed thread // This was successful since 'foo()' is again printing
foo()
foo()
foo()
foo()
s
Successfully suspended thread // Worked again
k
Successfully terminated thread // Says it works...
r
Successfully resumed thread // Termination must have worked because resuming did not cause 'foo' to start printing
e
waiting to exit main...
exiting...