qq_30069409
wanwan_1996
2017-06-08 10:45
采纳率: 35.7%
浏览 1.7k

C/C++线程池问题,销毁线程时程序段出错

在测试函数中调用StopAll线程退出失败,产生SIGSEGV信号,原因是什么?

 #include "threadpool.h"
#include <iostream>
#include <vector>
using namespace std;

CTask::CTask(string name)
{
    this->m_strTaskName = name;
    this->m_ptrData = NULL;
}

void CTask::setdata(void *data)
{
    this->m_ptrData = data;
}

/********************************************************************************************************************************************/
/**
    @static 变量在类外进行初始化
    */
vector<CTask *> CThreadPool::m_vecTaskList;
bool CThreadPool::shutdown = false;
pthread_mutex_t CThreadPool::m_pthreadMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t CThreadPool::m_pthreadCond =  PTHREAD_COND_INITIALIZER;

/**
    @ 构造函数初始化要创建线程池里的线程数量 
    */
CThreadPool::CThreadPool(int threadNum)
{
    this->m_iThreadNum = threadNum;
    this->CreatePool();
}

/**
    @ 向任务队列中添加任务,需要进行加锁处理
    @ 成功返回0
    */
int CThreadPool::AddTask(CTask *task)
{
    pthread_mutex_lock(&m_pthreadMutex);
    this->m_vecTaskList.push_back(task);
    cout << "add task successful the task vector size is" << this->getTaskSize() << endl;
    pthread_mutex_unlock(&m_pthreadMutex);
    pthread_cond_signal(&m_pthreadCond);

    return 0;
}

/**
    @ 唤醒所有线程让其退出并且销毁互斥锁与条件变量释放内存空间
    @ 重复关闭返回-1
    @ 成功关闭返回0
    */
int CThreadPool::StopAll()
{
    if(shutdown)
    {
        return -1;  
    }

    shutdown = true;
    pthread_cond_broadcast(&m_pthreadCond);

    for(int i = 0; i < m_iThreadNum; ++ i)
    {
        pthread_join(pthread_id[i], NULL);  
    }

//  delete[] pthread_id;

//  pthread_mutex_destroy(&m_pthreadMutex);
//  pthread_cond_destroy(&m_pthreadCond);

    return 0;
}

/**
    @ 返回当前任务列表里面的任务数量
    */
int CThreadPool::getTaskSize()
{
    return this->m_vecTaskList.size();
}


/**
    @   创建线程
    @ 成功返回0
    */
int CThreadPool::CreatePool()
{
    this->pthread_id = new pthread_t(m_iThreadNum);

    for(int i = 0; i < this->m_iThreadNum; ++ i)
    {
        pthread_create(&pthread_id[i], NULL, ThreadFunc, NULL); 
    }

    return 0;
}

void *CThreadPool::ThreadFunc(void *arg)
{
    pthread_mutex_lock(&m_pthreadMutex);
    pthread_t tid = pthread_self();
    pthread_mutex_unlock(&m_pthreadMutex);
    cout << tid << endl;
    while(1)
    {
        pthread_mutex_lock(&m_pthreadMutex);

        while(m_vecTaskList.size() == 0 && !shutdown)
        {
            cout << "cond_wait id is:" << tid << endl;
            pthread_cond_wait(&m_pthreadCond, &m_pthreadMutex); 
        }

        if(shutdown)
        {
            cout << "thread " << tid << " exit" << endl;
            pthread_mutex_unlock(&m_pthreadMutex);
            pthread_exit(NULL); 
        }

        vector<CTask *>::iterator iter = m_vecTaskList.begin();
        CTask *temp = NULL;

        if(iter != m_vecTaskList.end())
        {
            temp = *iter;
            m_vecTaskList.erase(iter);
        }

        pthread_mutex_unlock(&m_pthreadMutex);  

        temp->run();
    }   

    pthread_exit(NULL);
}


int main (void)
{
    cout << "begin............." << endl;
    CThreadPool pool(5);

    for(int i = 0; i < 50; ++ i)
    {
        CTask *task = new CTask();
        pool.AddTask(task);
    }
    while(pool.getTaskSize() != 0)
    {
        cout << pool.getTaskSize() << endl; 
        continue;   
    }

    pool.StopAll();
    cout << "end..............." << endl;   
    return 0;   
}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • nust20
    nust20 2017-06-09 08:04
    已采纳

    CThreadPool::CreatePool()中:
    this->pthread_id = new pthread_t(m_iThreadNum);
    修改为:
    this->pthread_id = new pthread_t[m_iThreadNum];

    原语句只申请了一个pthread_t类型的空间,而代码中需要m_iThreadNum个pthread_t的数组。
    你也知道,内存踩踏,可能出现各种奇怪的问题。

    希望采纳。

    另外代码中还有一个并发同步的问题,会引起线程死锁。如下,shutdown赋值,前后加锁。
    pthread_mutex_lock(&m_pthreadMutex);
    shutdown = true;
    pthread_cond_broadcast(&m_pthreadCond);
    pthread_mutex_unlock(&m_pthreadMutex);

    点赞 评论
  • nust20
    nust20 2017-06-09 02:37

    把这个#include "threadpool.h"文件贴出来看看呢

    点赞 评论
  • qq_30069409
    wanwan_1996 2017-06-09 02:53
     #ifndef _THREAD_H_
    #define _THREAD_H_
    
    #include <iostream>
    #include <vector>
    #include <string>
    #include <pthread.h>
    #include <algorithm>
    using namespace std;
    
    class CTask
    {
        public:
                    CTask(){}
                    CTask(string name);
                    virtual ~CTask(){}
    
        public:
                    virtual void run()
                    {
                        cout << "hello world" << endl;  
                    }
                    void setdata(void *data);
    
        protected:
                    string m_strTaskName;
                    void *m_ptrData;
    
    };
    
    /*******************************************************************************************************************************************/
    
    class CThreadPool
    {
        public:
                    CThreadPool(int threadNum = 10);
                    int AddTask(CTask *task);
                    int StopAll();
                    int getTaskSize();
    
        protected:
                    int CreatePool();
                    static void *ThreadFunc(void *arg);
        //          static int MoveToIdle(pthread_t tid);
            //      static int MoveToBusy(pthread_t tid);
    
        private:
                    static  vector<CTask*> m_vecTaskList;    
                static  bool shutdown;                 
                int m_iThreadNum;                    
                pthread_t   *pthread_id;  
    
                static pthread_mutex_t m_pthreadMutex;    
                static pthread_cond_t m_pthreadCond;
    
    };
    
    #endif
    
    
    
    
    
    点赞 评论

相关推荐