wanwan_1996 2017-06-08 02:45 采纳率: 0%
浏览 1727
已采纳

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 2017-06-09 00: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);

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 全志t113i启动qt应用程序提示internal error
  • ¥15 ensp可以看看嘛.
  • ¥80 51单片机C语言代码解决单片机为AT89C52是清翔单片机
  • ¥60 优博讯DT50高通安卓11系统刷完机自动进去fastboot模式
  • ¥15 minist数字识别
  • ¥15 在安装gym库的pygame时遇到问题,不知道如何解决
  • ¥20 uniapp中的webview 使用的是本地的vue页面,在模拟器上显示无法打开
  • ¥15 网上下载的3DMAX模型,不显示贴图怎么办
  • ¥15 关于#stm32#的问题:寻找一块开发版,作为智能化割草机的控制模块和树莓派主板相连,要求:最低可控制 3 个电机(两个驱动电机,1 个割草电机),其次可以与树莓派主板相连电机照片如下:
  • ¥15 潜在扩散模型的Unet特征提取
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部