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

基于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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值