mercredi 6 avril 2016

How to improve `thread_guard` for `std::thread`

// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <thread>
#include <iostream>

class thread_guard
{
    std::thread& t;
public:
    explicit thread_guard(std::thread& t_) :
        t(t_)
    {}
    ~thread_guard()
    {
        if (t.joinable())
        {
            t.join();
            std::cout << "t is joined" << std::endl;
        }
    }
    thread_guard(thread_guard const&) = delete;
    thread_guard& operator=(thread_guard const&) = delete;
};

struct func
{
    int& i;

    func(int& i_) :i(i_) {}

    void operator()()
    {
        //throw 1;
    }
};

void do_something_in_current_thread()
{   
    std::cout << "do_something_in_current_thread" << std::endl;
    // throw 2; // where t.join will be called!
}


void f()
{
    int some_local_state; // don't care
    func my_func(some_local_state);
    std::thread t(my_func); // my_func throws exception!
    thread_guard g(t);

    do_something_in_current_thread();
}

int main()
{
    f();
}

If the thread function(i.e. my_func) throws exception. The t.join will not be called through thread_guard because the construction of thread_guard is not reached yet.

Question> How to improve thread_guard so that the t.join will always be called even if the thread function throws exception?

Aucun commentaire:

Enregistrer un commentaire