首页 > 技术文章 > 线程基类的构建与代码实践

share-ideas 2019-05-18 16:30 原文

  1. 在C++中常用到线程来执行相应的任务,一般会构建一个线程基类,其他的线程类型通过继承的方式来实现不同的功能。
  2. 所实现的代码考虑了windows和linux平台的兼容性,且具有代表性,在工程实践中具有参考价值。
  3. 在创建线程时,对线程的属性进行了设置,如堆栈大小,以及设置线程为分离状态,从而可以在线程结束时可自动释放资源。
  4. 提供一个整体性的线程框架,继承该基类的线程只要实现相应的work函数即可处理相应的任务。
class ThreadBase
{
protected:
    
#ifdef LINUX
    pthread_t thread_id;
#endif
#ifdef WIN32
    HANDLE thread_id;
#endif
    
public:
    bool run_flag;
    bool is_end;
    
public:
    ThreadBase();
    ~ThreadBase();
    int start();
    void stop();
    bool isEnd();
    virture int process(); //子类来重写
#ifdef LINUX
    static void* run(void* arg);
#endif

#ifdef WIN32
    static void run(void* arg);
#endif

}

void stop()
{
    run_flag = false;
}

bool isEnd()
{
    return is_end;
}

int start()
{
    if (run_flag)
    {
        return 0;
    }
    
#ifdef LINUX
    pthread_attr_t thread_attr;
    pthread_attr_init(&thread_attr);
    pthread_attr_setstacksize(&thread_attr, 1024 * 10); //设置线程的堆栈大小
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);    //设置线程为分离状态,即当线程结束时会自动释放资源。若是未分离状态,需要在主线程中调用join来释放。
    int ret = pthread_create(&thread_id, &thread_attr, ThreadBase::run, (void*)this);
    if (ret != 0)
    {
        printf("create failed, errno[%d],desc[%s]", errno, strerror(errno));
        pthread_attr_destroy(&thread_attr);
        return -1;
    }
    else
    {
        pthread_attr_destroy(&thread_attr);
        return 0;
    }
#endif    
    
#ifdef WIN32
    thread_id = (HANDLE)_beginthread(ThreadBase::run, 0, (void*)this);
    if (thread_id == 0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
#endif    
    
}

int process()
{
    while(run_flag)
    {
        work();
    }
}



#ifdef LINUX
void* ThreadBase::run(void* arg)
{
    CThreadBase * pThread = (CThreadBase * )arg;
    pThread->run_flag = true;
    pThread->is_end = false;
    pThread->process();
    pThread->is_end = true;

    return NULL;
}
#endif



#ifdef WIN32
void ThreadBase::run(void* arg)
{
    ThreadBase * pThread = (ThreadBase * )arg;
    pThread->run_flag = true;
    pThread->is_end = false;
    pThread->process();
    pThread->is_end = true;

    return;
}
#endif

ThreadBase::~ThreadBase()
{
    stop();
}
ThreadBase::ThreadBase()
{
    run_flag = false;
    is_end = true;
}

 

推荐阅读