zwfars
zwfars

Reputation: 41

Why does my thread never ends

I want to implement a thread pool using C++11.It was a template class composed of a work_queue,a worker funciton and a vector of threads. Here is my h-file

#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <vector>
#include <list>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>

// a threadpool with template
template<typename T>
class threadpool {
public:
    threadpool(int thread_num, int request_num);
    bool add_requests(T* request);
    void run();
    ~threadpool();

private:
    //the vector of multiple thread
    std::vector<std::thread> threads;
    // the task queue
    std::list<T*> work_queue;

    //synchronization
    std::mutex queue_mutex;
    std::condition_variable condition;
    int  max_requests;
    bool stop;


};

//the worker function
template<typename T>
void threadpool<T>::run() {
    while (1) {
        T* request;
        {
            std::unique_lock<std::mutex> lock(this->queue_mutex);
            condition.wait(lock, [this] {return !(this->work_queue.empty()); }); 
            if (this->stop&&this->work_queue.empty())
                return;
            request = work_queue.front();
            work_queue.pop_front();
        }
        request->process();
    }
}

//add new work item to the pool
template<typename T>
bool threadpool<T>::add_requests(T* request) {
    std::unique_lock<std::mutex> lock(this->queue_mutex); 
    if (work_queue.size() >= max_requests)
        return false;
    work_queue.push_back(request);
    condition.notify_one();
    return true;
}
// the constructor
template<typename T>
inline threadpool<T>::threadpool(int thread_num, int request_num) :max_requests(request_num), stop(false) {
    for (int i = 0; i < thread_num; ++i)
        threads.emplace_back(&threadpool::run, this);

}

// the destructor joins all threads
template<typename T>
inline threadpool<T>::~threadpool()
{
    {
        std::unique_lock<std::mutex> lock(queue_mutex);
        stop = true;
    }
    condition.notify_all();
    //there is an error, the thread never stops...
    for (std::thread &worker: threads)
        worker.join();
}

#endif

And my test code is as follows. There are some errors. There seems a deadlock on my thread.join(),could any one tell me why?

//for test my thread pool
#include"threadpool.h"
#include<iostream>
#include<ctime>
#include <windows.h>

struct node {

    static int cur;
    void process(){
        ++cur;
        std::cout << cur << std::endl;
        Sleep(2000);
    }
};

int node::cur = 10;

int main()
{
    threadpool<node> haha(4, 5);
    clock_t start;
    clock_t end;
    node a1;
    node a2;
    node a3;
    //start = clock();
    //add request
    haha.add_requests(&a1);
    haha.add_requests(&a2);
    haha.add_requests(&a3);
    return 0;

}

Upvotes: 0

Views: 265

Answers (1)

user7860670
user7860670

Reputation: 37468

Your condition variable predicate may not break the wait when you set stop to true at destructor, so you should check stop inside as well:

condition.wait(lock, [this] {return this->stop || !(this->work_queue.empty()); });

Upvotes: 1

Related Questions