vendredi 16 novembre 2018

Launching thread through Constructor in C++11

I am trying to execute the program where I create a queue of packaged_task and try to execute the packaged_tasks in a separate thread. I am getting the following error

Error C2664 'std::function<_Ret (void)>::function(std::function<_Ret (void)> &&)': cannot convert argument 1 from 'std::_Binder' to 'std::nullptr_t'

The code I have is shown below. Could any one guide as to why this error happens ?

/*
****************************************************************************************************
                                        The Header File
****************************************************************************************************
*/


class CommandChannel {
private:
    std::thread commChannelThread;
    std::mutex commChannelmu;
    std::condition_variable commChannelcv;


    struct taskRequest
    {};
    struct taskResponse
    {};

    /* Creates a queue of packaged tasks that accepts one iu */
    std::deque< std::packaged_task<int()>> comm_ch_task_queue;

    void threadHandler(void);

protected:
    int p_impl_theAdd(int a, int b);
    int p_impl_theMul(int a, int b);
    int p_impl_theDiv(int a, int b);
public:
    /*Constructor and the Destructor*/
    CommandChannel();
    ~CommandChannel();

    /*The public functions */
    int theAdd(int a, int b);
    int theMul(int a, int b);
    int theDiv(int a, int b);
};

    /*
    ****************************************************************************************************
                                            The Implementation File
    ****************************************************************************************************
    */

/* Implementation Functions */
int CommandChannel::p_impl_theAdd(int a, int b)
{
    return a+b;
}

int CommandChannel::p_impl_theMul(int a, int b)
{
    return a*b;
}

int CommandChannel::p_impl_theDiv(int a, int b)
{
    return a / b;
}


/* COnstructors and Destructors */
CommandChannel::CommandChannel()
{
    /*Creating a new thread that runs the threadHandler function*/
    commChannelThread = std::thread(&CommandChannel::threadHandler, this);
}
CommandChannel::~CommandChannel()
{
    if (commChannelThread.joinable()) {
        commChannelThread.join();
        std::cout << "Command Channel Thread Joined " << std::endl;
    }
    else
        std::cout << "Problem in joining the Command Channel Thread" << std ::endl;
}

/*  User Public Functions  */
int CommandChannel::theAdd(int a, int b)
{
    /* Creating the packaged task with the the implementation pointer */
    std::packaged_task<int()> t(std::bind(&CommandChannel::p_impl_theAdd, a, b));

    /* Pushing the task in the queue */
    {
        std::lock_guard<std::mutex> locker(commChannelmu);
        comm_ch_task_queue.push_back(t);
        commChannelcv.notify_one();
    }

    /* creating the placeholder for the return value */
    std::future<int> fu = t.get_future();

    /* getting the value from the future */
    return fu.get();

}

int CommandChannel::theMul(int a, int b)
{
    /* Create the packaged task with the pimpl */
    std::packaged_task<int()> t(std::bind(&CommandChannel::p_impl_theMul, a, b));

    /* Pushing the task in the queue */
    {
        std::lock_guard<std::mutex> locker(commChannelmu);
        comm_ch_task_queue.push_back(t);
        commChannelcv.notify_one();
    }

    /* Creating the placeholder for the return value */
    std::future<int> fu = t.get_future();

    /*getting the value from the future*/
    return fu.get();
}

int CommandChannel::theDiv(int a, int b)
{
    /* Create the packaged tasks with the pimpl */
    std::packaged_task<int()> t(std::bind(&CommandChannel::p_impl_theDiv, a, b));

    /*Pushing the task in the queue thorigh the mutex locks*/
    {
        std::lock_guard<std::mutex> locker(commChannelmu);
        comm_ch_task_queue.push_back(t);
        commChannelcv.notify_one();
    }
    /* Creating the placeholder for the return value */
    std::future<int> fu = t.get_future();

    /*getting the value from the future*/
    return fu.get();
}


/* 
   Thread Handler

   Pops the elemetns from the queue and then executes them
   the value goes to the called function through future references
*/
void CommandChannel::threadHandler()
{
    std::packaged_task<int()> t;
    {
        std::unique_lock<std::mutex> locker(commChannelmu);
        commChannelcv.wait(locker);
        t = std::move(comm_ch_task_queue.front());
        comm_ch_task_queue.pop_front();
    }
    t();
}


    /*
    ****************************************************************************************************
                                            Main
    ****************************************************************************************************
    */

int main()
{
    CommandChannel api;

    api.theAdd(2, 4);
    api.theDiv(6, 3);
    api.theMul(5, 7);

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire