基于UDP的P2P聊天工具 0.4——线程的和平退出

来源:互联网 发布:淘宝详情页源代码 编辑:程序博客网 时间:2024/06/04 18:33

基于UDP的P2P聊天工具 0.4——线程的和平退出


简介:
1)这是一个Windows的P2P聊天工具的线程管理部分;
2)Thread.h和Thread.cpp可以拿出来用,不受其它部分干扰;
3)相比0.3版,它考虑了线程的和平退出,仍然局域网;


相关内容:
1)线程的和平退出


一、线程的和平退出
通常,对于线程的终止,大致上有两类。一种是类似于TerminateThread的方法,另一种是由线程主动退出。前者的有点在于高效和直接,缺点在于可能造成资源的释放失败。所以,这里采用线程主动return退出的方式进行处理。


操作上,我们可以采用线程函数+任务函数的方式进行处理。当线程对象被赋予一个任务时,由线程函数调用该任务;当线程对象收到终止命令时,由线程函数控制和平退出。一种较为简介的方式可以像这样:

while( !b_stop ){    task();}


二、std::thread的封装
这里使用unique_ptr来管理thread。它们俩有一个相似之处,就是都不允许拷贝。那么,假设要使用vector来进行管理,建议使用move语义,如vec.push_back(temp)


这里的线程函数,主要由控制变量和for循环构成,然后对任务函数进行调用。任务函数则需要先调用SetRun进行设置。


因为代码比较短,这里就直接上代码了。下面是Thread.h和Thread.cpp。

/****************************************       class Thread*       负责调用任务函数和启停线程****************************************/#pragma once#include <thread>#include <memory>#include <functional>#include <chrono>using namespace std;enum class SType { THREAD_JOIN, THREAD_DETACH };class Thread{public:    ~Thread();    // 设置任务函数,并设置循环次数    bool SetRun(function<void(void)> func, int times = 1);    // 启动线程: 若未设置任务函数,或正在运行,则返回失败    bool Start(SType type = SType::THREAD_DETACH);    // 停止线程: 停止对任务的循环执行,而当前任务会正常执行    void Stop();private:    unique_ptr<thread> m_thread;    function<void(void)> m_task;    // 任务函数    int m_times;        // 线程中,当前任务的执行次数    bool m_started;     // 当前线程运行状态    // 作为线程函数,循环调用任务函数    void m_threadRun();};
#include "Thread.h"Thread::~Thread(){    Stop();}// 设置任务函数,并设置循环次数bool Thread::SetRun(function<void(void)> func, int times){    if (!m_started)    {        m_task = func;        m_times = times;        return true;    }    return false;}// 启动线程bool Thread::Start(SType type){    // 若未设置任务函数,或正在运行,则返回false;    if (!m_task || m_started)        return false;    m_started = true;    m_thread = make_unique<thread>(        thread(bind(&Thread::m_threadRun, this))        );    if (type == SType::THREAD_DETACH)        m_thread->detach();    else        m_thread->join();    return true;}// 停止线程: 停止对任务的循环执行,而当前任务会正常执行void Thread::Stop(){       m_started = false;}// 作为线程函数,循环调用任务函数void Thread::m_threadRun(){    if (!m_started || !m_task)        return;    // 若预设执行次数小于等于0,则持续循环,直到线程被终止    for (int i = 0; (i < m_times || m_times<=0) && m_started; i++)    {        m_task();        this_thread::sleep_for(chrono::milliseconds(100));    }    m_started = false;}


若有兴趣,完整的代码下面的地址。不过有些东西还在改。
https://github.com/Jiacheng03/Hailer

原创粉丝点击