Kwo0D
2021-10-18 13:05
采纳率: 0%
浏览 35
已结题

为什么这个线程池有时候会double free?


#include<pthread.h>
#include<unistd.h>
#include<list>
#include<stdio.h>
#include<vector>
#include<list>
static int i = 0;

class Lock{
    public:
        Lock() {
            pthread_mutex_init(&lock_, NULL);
        }
        ~Lock() {
            pthread_mutex_unlock(&lock_);
        }
        void lock() {
            pthread_mutex_lock(&lock_);
        }
        void unlock() {
            pthread_mutex_unlock(&lock_);
        }
    private:
        pthread_mutex_t lock_;
};

class Sem{
    public:
        Sem() {
            pthread_cond_init(&cond_, NULL);
        }
        ~Sem() {
            pthread_cond_broadcast(&cond_);
        }
        void wait() {
            pthread_cond_wait(&cond_, &lock_);
        }
        void post() {
            pthread_cond_signal(&cond_);
        }
    private:
        pthread_mutex_t lock_;
        pthread_cond_t cond_;
};

template <typename T>
class ThreadPool {
    public:
        ThreadPool(int thd_num = 8, int max_req = 10000);
        ~ThreadPool();

        bool append(T* request);
    private:
        static void* worker(void* args);
        void run();
        int max_threads_number_;
        int max_requests_number_;
        std::vector<pthread_t> threads_;
        std::list<T*> works_;
        Lock lock_;
        Sem sem_;
        bool stop_;
};
template <typename T> 
ThreadPool<T>::ThreadPool(int thread_number, int max_request):max_threads_number_(thread_number), max_requests_number_(max_request),stop_(false),works_() {
    if(thread_number <= 0 || max_request <= 0) {
        throw std::exception();
    }
    //threads_ init
    threads_ = std::vector<pthread_t>(max_threads_number_);

    for(int i = 0;i<max_threads_number_; ++i) 
    {
        //create pool
        if (pthread_create(&threads_[i], NULL, worker, this) != 0) {
            throw std::exception();
       
        }
        if (pthread_detach(threads_[i])) {
            throw std::exception();
        }
        printf("thread start!%d\n", threads_[i]);
    }
}

template<typename T>
ThreadPool<T>::~ThreadPool() {
    stop_ = true;
}

template<typename T>
bool ThreadPool<T>::append(T *request) {
    lock_.lock();
    if (this->works_.size() > max_requests_number_) {
        lock_.unlock();
        return false;
    }
    works_.push_back(request);
    printf("%d get work\n", getpid());
    sem_.post();
    lock_.unlock();
    return true;
}

template<typename T> 
void* ThreadPool<T>::worker(void* arg) {
    ThreadPool* self = (ThreadPool*)arg;
    self->run();
    return self;
}

template<typename T>
void ThreadPool<T>::run() {
    while(!stop_)
    {
        while(works_.empty())sem_.wait();
        lock_.lock();
        T* request = works_.front();
        works_.pop_front();
        lock_.unlock();
        ++i;
    }
}
void foo() {
    ++i;
}
typedef void (*task)();
int main() {
    ThreadPool<task> pool(200);
    task f = foo;
    for(int i = 0;i<10000;i++){printf("add work!\n");pool.append(&f);}
    sleep(1);
    printf("%d", i);
}

一般都是add work的时候会出现free两次

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 邀请回答

1条回答 默认 最新

相关推荐 更多相似问题