C++11 多线程模块封装

C++ 线程类封装

在实现一个通知的时候上网找资料,发现这位大佬的实现跟我极其相似,草哈哈哈哈

当然线程模块还有很多实现方式

  1. 比如在Task中定义线程入口函数,外部去注册函数,然后运行。
  2. 也可以是不让Task成为抽象类,可以作为外面功能模块的成员,接收外面功能模块的函数注册,然后运行,都可以。

对了其中std::optional 是cpp17的 你可以替换成bool类型
不多说了,直接上代码
task.hpp

#pragma once

#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>

namespace utility {
class Task {
  enum class State : char {
    kEnd,
    kPaused,
    kRunning,
  };

 public:
  Task(bool autoStop);
  virtual ~Task();

  bool start();
  bool stop();
  bool pause();
  bool resume();

 protected:
  virtual bool threadProcess() = 0;

 private:
  void run();

 private:
  State state_;
  std::atomic_bool autoStop_;
  std::unique_ptr<std::thread> task_;
  std::mutex lock_;
  std::condition_variable cv_;
};
}  // namespace utility

task.cpp

#include "utils_thread.hpp"

#include <iostream>

#include "iso646.h"

namespace utility {
Task::Task(bool autoStop) : state_{State::kEnd}, autoStop_{autoStop}, task_{} {}

Task::~Task() { task_.reset(); }

bool Task::start() {
  if (nullptr != this->task_.get() and this->state_ == State::kRunning) {
    return true;
  }

  state_ = State::kRunning;
  task_.reset(new std::thread(&Task::run, this));
  return true;
}

bool Task::stop() {
  if (nullptr == this->task_.get() and State::kEnd == this->state_) {
    return true;
  }

  if (nullptr != this->task_.get() and State::kPaused == this->state_) {
    std::cout << "make run\n";
    resume();  // 由挂起变为运行
  }

  // 通过上面流程,以下为运行状态
  this->state_ = State::kEnd;

  if (!this->task_->joinable()) {
    std::cout << "joinable : false\n";
    return false;
  }
  this->cv_.notify_one();
  this->task_->join();
  this->task_.reset();

  return true;
}

bool Task::pause() {
  if (nullptr != this->task_.get() and State::kRunning == this->state_) {
    this->state_ = State::kPaused;
    return true;
  }
  return false;
}

bool Task::resume() {
  if (nullptr != this->task_.get() and State::kPaused == this->state_) {
    this->state_ = State::kRunning;
    this->cv_.notify_one();
    return true;
  }
  return false;
}

auto Task::run() -> void {
  std::cout << "run pid:" << std::this_thread::get_id() << std::endl;

  do {
    if (this->autoStop_.load() == true) {
      if (!threadProcess()) {
        pause();
      }
    } else {
      threadProcess();
    }

    while (State::kPaused == this->state_) {
      std::unique_lock<std::mutex> locker(this->lock_);
      std::cout << "sleep" << std::endl;
      this->cv_.wait(locker);
      std::cout << "wake up, "
                << " now state:" << int(this->state_) << std::endl;
    }

  } while (State::kEnd != this->state_);

  std::cout << "exit pid:" << std::this_thread::get_id() << std::endl;
}
}  // namespace utility

woker.hpp
Woker 继承 utility::Task,实现threadProcess()接口

#pragma once

#include "utils_thread.hpp"

class Worker : public utility::Task {
public:
  Worker() : utility::Task(true) { }

  ~Worker() override {
    stop();
  }

  bool threadProcess() override {
    std::string str("nihao!");
    std::cout << str << "\t";
    
    using namespace std::literals;
    std::this_thread::sleep_for(10ms);
    return true;
  }
};

main.cpp

#include "woker.hpp"

using namespace std::literals;

int main() {
  Worker woker{};
  woker.start();
  std::this_thread::sleep_for(3s);
  woker.pause();
  std::this_thread::sleep_for(3s);
  woker.resume();
  std::this_thread::sleep_for(3s);
  woker.stop();

  return 0;
}

后续会在work::Task类上做扩展,实现zmq网络收发模块的集成,以及实现一个v4l2+ffmpeg的一套流程。
to be continue...

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 在UE4中,可以通过使用多线程来运行插件,以提高程序的性能和并行处理能力。 首先,插件在UE4中是以模块的形式存在的,可以独立于游戏项目而存在。为了实现多线程运行插件,可以在插件的模块中编写异步任务,利用多线程来执行这些任务。 在UE4中,我们可以使用FRunnable接口来创建自定义线程。首先,需要创建一个继承自FRunnable的类,并实现必要的接口函数,如Run和Stop。在Run函数中,编写插件需要执行的任务代码。 在插件的初始化阶段,可以通过调用FRunnableThread::Create函数来创建一个新的线程,并指定我们刚刚定义的FRunnable类对象作为参数。然后,可以开始执行插件任务。 需要注意的是,在多线程编程中,需要合理地处理线程之间的数据共享和同步问题。可以使用一些线程同步的机制,如互斥锁、信号量等,来避免多个线程同时操作共享数据导致的冲突。 另外,UE4还提供了一些已经封装好的多线程工具类,如FGraphEvent和FQueuedThread等,可以帮助我们更方便地实现多线程任务的管理和同步。 总结来说,UE4中可以通过使用FRunnable接口和多线程工具类来实现插件的多线程运行。合理地设计和管理多线程任务,可以提高程序的性能和并行处理能力,并且确保线程之间的数据共享和同步的正确性。 ### 回答2: 在UE4中,我们可以通过多线程来实现插件的运行。多线程是一种并发执行任务的方式,可以让程序同时执行多个任务,提高了程序的效率和性能。 在UE4中,我们可以使用一些多线程的技术来实现插件的运行。比如,使用C++中的std::thread来创建多个线程,并让每个线程在后台执行插件相关的任务。同时,我们还可以使用一些线程同步的机制,比如互斥锁、条件变量等来管理多个线程之间的资源访问和共享。 在插件的运行过程中,可以将一些耗时的任务放在单独的线程中执行,这样就不会阻塞主线程的执行。比如,可以将插件中的某个算法或者处理逻辑放在一个独立的线程中运行,这样主线程可以继续执行其他的任务,提高了程序的响应速度和用户体验。 除了使用多线程,还可以使用UE4中提供的任务图谱系统来实现插件的并行执行。任务图谱系统可以将任务划分成多个小任务,并按照依赖关系进行调度,从而充分利用计算资源并提高任务执行的效率。 总结来说,UE4中可以通过多线程技术来实现插件的运行,可以提高程序的效率和性能,同时还可以使用任务图谱系统来实现任务的并行执行。这些技术可以充分发挥计算资源的利用率,提高插件的运行效果和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

歪锅锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值