Using C++, I would like to start a thread from a void method and then return before the thread may have finished. For example:
#include <thread>
using namespace std;
void longFunc(){
//stuff
}
void startThread(){
thread t(longFunc);
}
int main(void){
startThread();
//lots of stuff here...
return 0;
}
When the startThread() finishes, t tries to be deleted, and fails. How can I do this?
If you really want a fire-and-forget pattern, you can just detach from the thread:
void startThread(){
thread t(longFunc);
t.detach();
}
Or if you need to join the thread (which is most often a reasonable thing), you could simply return an std::thread object by value (thread wrappers are moveable):
std::thread startThread()
{
return std::thread(longFunc);
}
Anyway, you may consider launching the thread through std::async() and returning a future object instead. This would be exception-safe, since exceptions thrown in the launched thread will be swallowed by the future object, and thrown again in the main thread when you invoke get() on it:
#include <thread>
#include <future>
void longFunc()
{
//stuff
}
std::future<void> startThread()
{
return std::async(std::launch::async, longFunc);
}
int main(void)
{
auto f = startThread();
//lots of stuff here...
// For joining... (wrap in a try/catch block if you are interested
// in catching possible exceptions)
f.get();
}
Related
I have one main thread that will send an async job to the task queue on the other thread. And this main thread can trigger a destroy action at any time, which could cause the program to crash in the async task, a piece of very much simplified code like this:
class Bomb {
public:
int trigger;
mutex my_mutex;
};
void f1(Bomb *b) {
lock_guard<std::mutex> lock(b->my_mutex); //won't work! Maybe b have been destructed!
sleep(1);
cout<<"wake up.."<<b->trigger<<"..."<<endl;
}
int main()
{
Bomb *b = new Bomb();
b->trigger = 1;
thread t1(f1, b);
sleep(1);
//lock here won't work
delete b;//in actual case it is triggered by outside users
t1.join();
return 0;
}
The lock in f1 won't work since the destructor can be called first and trying to read mutex will crash. Put lock in destructor or before the delete also won't work for the same reason.
So is there any better way in this situation? Do I have to put mutex in the global scope and inside destructor to solve the issue?
In code, my comment looks like this :
#include <future>
#include <mutex>
#include <iostream>
#include <chrono>
#include <thread>
// do not use : using namespace std;
class Bomb
{
public:
void f1()
{
m_future = std::async(std::launch::async,[this]
{
async_f1();
});
}
private:
void async_f1()
{
using namespace std::chrono_literals;
std::lock_guard<std::mutex> lock{ m_mtx };
std::cout << "wake up..\n";
std::this_thread::sleep_for(1s);
std::cout << "thread done.\n";
}
std::future<void> m_future;
std::mutex m_mtx;
};
int main()
{
{
std::cout << "Creating bomb\n";
Bomb b; // no need to use unecessary new
b.f1();
}
std::cout << "Bomb destructed\n";
return 0;
}
I want to create a thread that can be interrupted while waiting (it waits data from other processes and I want to stop the process in nice way).
I've read the 9.2 part of C++ Concurrency in Action 2nd Edition, and I've tried to implement that ideas, but I've some problem and I don't know where to check.
This is my code based on that example:
#include <iostream>
#include <stdexcept>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <future>
// Exception that should be raised when there's an interruption.
// It's raised when the thread is interrupted, so we can catch
// it and finish the thread execution.
class InterruptedException : public std::runtime_error {
public:
InterruptedException(const std::string& message) : std::runtime_error(message) {}
virtual ~InterruptedException() {}
};
// Interrupt flag. This class represents a local-thread flag that
// tells if the thread is interrupted or not.
class InterruptFlag {
public:
InterruptFlag() :
m_threadConditionVariable(nullptr),
m_threadConditionVariableAny(nullptr) {}
void set() {
m_flag.store(true, std::memory_order_relaxed);
std::lock_guard<std::mutex> lk(m_setClearMutex);
if (m_threadConditionVariable) {
m_threadConditionVariable->notify_all();
}
else if (m_threadConditionVariableAny) {
m_threadConditionVariableAny->notify_all();
}
}
template <typename Lockable>
void wait(std::condition_variable_any& cv, Lockable& lk) {
struct CustomLock {
InterruptFlag* m_self;
Lockable& m_lk;
CustomLock(InterruptFlag* self, std::condition_variable_any& cond, Lockable& lk) :
m_self(self),
m_lk(lk) {
m_self->m_setClearMutex.unlock();
m_self->m_threadConditionVariableAny = &cond;
}
void unlock() {
m_lk.unlock();
m_self->m_setClearMutex.unlock();
}
void lock() {
std::lock(m_self->m_setClearMutex, lk);
}
~CustomLock() {
m_self->m_threadConditionAny = nullptr;
m_self->m_setClearMutex.unlock();
}
};
CustomLock cl(this, cv, lk);
InterruptPoint();
cv.wait(cl);
InterruptPoint();
}
void setConditionVariable(std::condition_variable& cv) {
std::lock_guard<std::mutex> lk(m_setClearMutex);
m_threadConditionVariable = &cv;
}
void clearConditionVariable() {
std::lock_guard<std::mutex> lk(m_setClearMutex);
m_threadConditionVariable = nullptr;
}
bool isSet() const {
return m_flag.load(std::memory_order_relaxed);
}
private:
std::atomic<bool> m_flag;
std::condition_variable* m_threadConditionVariable;
std::condition_variable_any* m_threadConditionVariableAny;
std::mutex m_setClearMutex;
};
// Thread-local interrupt flag instance. The variable should be
// created for every thread, since it's thread_local.
thread_local InterruptFlag ThisThreadInterruptFlag;
// Convenience class for cleaning the flag due to RAII.
struct ClearConditionVariableOnDestruct {
~ClearConditionVariableOnDestruct() {
ThisThreadInterruptFlag.clearConditionVariable();
}
};
// Function that throws the exception that tells that the thread
// is interrupted. For doing it checks the state of ThisThreadInterruptFlag.
void InterruptionPoint() {
if (ThisThreadInterruptFlag.isSet()) {
throw InterruptedException("Interrupted");
}
}
// Function that must be used inside the thread function body for waiting.
// It waits for the condition variable, when it notifies from other threads,
// but it also notifies if the thread is interrupted.
void InterruptibleWait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk) {
InterruptionPoint();
ThisThreadInterruptFlag.setConditionVariable(cv);
ClearConditionVariableOnDestruct guard;
InterruptionPoint();
cv.wait_for(lk, std::chrono::milliseconds(1));
InterruptionPoint();
}
// This class represents the interruptible thread. It adds a interrupt()
// method that when called interupts the thread execution, if it's waiting
// at some point where InterruptibleWait function is locked.
class Interruptible {
public:
template <typename FunctionType>
Interruptible(FunctionType f) {
std::promise<InterruptFlag*> p;
m_internalThread = std::thread([f, &p]() {
p.set_value(&ThisThreadInterruptFlag);
try {
f();
}
catch (InterruptedException) {
}
});
m_flag = p.get_future().get();
}
void join() {
m_internalThread.join();
}
void detach() {
m_internalThread.detach();
}
bool joinable() const {
return m_internalThread.joinable();
}
void interrupt() {
if (m_flag) {
m_flag->set();
}
}
private:
std::thread m_internalThread;
InterruptFlag* m_flag;
};
std::mutex mtx;
std::unique_lock<std::mutex> lk(mtx);
int main(int argc, char* argv[]) {
std::cout << "Interrupting thread example" << std::endl;
bool test = false;
std::condition_variable cv;
auto f = [&cv, &test]() {
test = true;
InterruptibleWait(cv, lk);
// Since it locks forever, it should never reach this point.
test = false;
};
Interruptible interruptibleThread(f);
std::this_thread::sleep_for(std::chrono::milliseconds(30));
// We interrupt the function while it's blocked in InterruptibleWait
interruptibleThread.interrupt();
interruptibleThread.join();
std::cout << "test value is " << std::boolalpha << test << ". It should be true." << std::endl;
return 0;
}
Basically I create a Interruptible class representing a thread that can be interrupted. I interrupt it during its execution by calling its interrupt() method. The thread can be interrupted if it's locked with in a InterruptibleWait function call. This function behave like a std::condition.wait(), in fact it wants a reference to it, but it also handle the interruption flag.
If I start the program. I obtain an error from Visual Studio when running.
I don't know what I'm doing wrong. What should I do in order to make InterruptibleWait work correctly?
My best guess based on the given information:
The exception isn't caught in the thread entry point function, and escapes that function. When this happens in a thread started by std::thread, abort is called for you (indirectly through std::terminate) by the std::thread implementation, as required by the standard. To fix this, try catching all exceptions in the function passed to std::thread.
See the cppreference articles on std::thread and std::terminate
Is it good or bad to create a thread in function object constructor by passing the dereferenced this pointer by reference to the thread object?
Is there any problem in below code?
Any improvement can be made on it to reach below objective?
The objective is to gracefully end the thread when the class object is out of scope.
#include <iostream>
#include <chrono>
#include <future>
#include <thread>
class MyThread {
private:
std::atomic<bool> exit;
std::thread t;
public:
MyThread() : exit(false) {
t = std::thread(std::ref(*this));
}
~MyThread() {
exit.store(true, std::memory_order_relaxed);
if (t.joinable()) {
t.join();
}
}
void operator()() {
while (!exit.load(std::memory_order_relaxed)) {
std::cout << "."; // some more meaningful work here
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
};
int main() {
MyThread t;
std::cin.get();
return 0;
}
It might work occasionally, but it's unsafe. It potentially generates a race condition, because you start the thread on an object that hasn't finished its construction yet, resulting in undefined behavior.
Why in this simple class if i use directly io.run() the function will be invoked otherwise if demand the run to other thread the print will not be invoked?
#include <iostream>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
using namespace std;
class test
{
public:
test()
{
io.post(boost::bind(&test::print, this));
//io.run();
t = boost::thread(boost::bind(&boost::asio::io_service::run, &io));
}
void print()
{
cout << "test..." << endl;
}
private:
boost::thread t;
boost::asio::io_service io;
};
int main()
{
test();
return 0;
}
The thread object is being destroyed before allowing the io_service to completely run. The thread destructor documentation states:
[...] the programmer must ensure that the destructor is never executed while the thread is still joinable.
If BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE is defined, the program would abort as the thread destructor would call std::terminate().
If the io_service should run to completion, then consider joining the thread within Test's destructor. Here is a complete example that demonstrates synchronizing on the thread's completion:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
class test
{
public:
test()
{
io.post(boost::bind(&test::print, this));
t = boost::thread(boost::bind(&boost::asio::io_service::run, &io));
}
~test()
{
if (t.joinable())
t.join();
}
void print()
{
std::cout << "test..." << std::endl;
}
private:
boost::thread t;
boost::asio::io_service io;
};
int main()
{
test();
return 0;
}
Output:
test...
io_service::run() will complete all outstanding tasks and return when complete. If you don't call it, it will do nothing. If you do something like this:
boost::asio::io_service::work work(io);
Another thread will do this for you and run until you stop it one way or another.
i wanna provide a class, that holds a buffer while reading in some data (udp packets or from a file). Everything is fine if i start my thread from the main, but in this case i want to avoid, that the user has to set up a new thread for himself.
so here is my code as simple as i could make it:
class DataCollector
{
void startCollect()
{
std::thread t1(readSource);
}
bool readSource()
{
while(1)
{
// read some data for storage
}
}
}
int main()
{
DataCollector myDataCollector;
myDataCollector.startCollect();
while(1)
{
// do some other work, for example interpret the data
}
return 0;
}
now i need your help. How can i call this thread inside startCollect?
edit1:
here is my example of how it works NOW!
// ringbuffertest.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//
#include "stdafx.h"
#include <thread>
#include <Windows.h>
class DataCollector
{
private:
//std::thread collecterThread;
public:
DataCollector(){}
void startCollect()
{
readSource();
}
bool readSource()
{
while (1)
{
printf("Hello from readSource!\n");
Sleep(1000);
}
return false;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
DataCollector myDataCollector;
std::thread t1(&DataCollector::startCollect, std::ref(myDataCollector));
t1.join();
return 0;
}
but as i said i would like to hide the thread call inside my startCollect function.
Before destroying an active thread object, it must either be joined (waiting for the thread to finish, then cleaning up its resources) or detached (left to run and clean itself up when finished).
So you could either make the thread a member variable, so that it can be joined later:
void startCollect()
{
this->thread = std::thread(&DataCollector::readSource, this);
}
void waitForCollectToFinish()
{
this->thread.join();
}
or you could detach it, if you don't need the ability to wait for it to finish, and have some other way of signalling that data is available:
void startCollect()
{
std::thread([this]{readSource();}).detach();
}
You might also look at higher-level concurrency facilities, such as std::async and std::future. These might be more convenient than dealing with threads directly.