任务队列C++实现-(完美转发)

打印 上一主题 下一主题

主题 883|帖子 883|积分 2649

需求


  • 任务队列中可以依次添加任务
  • 任务执行函数需要接受外部传输的参数
  • 主动调用Start开始执行任务
代码实现
  1. class TaskQueue {
  2. private:
  3.     std::mutex mtx;
  4.     std::condition_variable cv;
  5.     std::queue<std::function<void()>> task_queue;
  6.     std::atomic<bool> is_running;
  7. public:
  8.     TaskQueue() : is_running(false) {}
  9.     ~TaskQueue() {}
  10.     // std::forward is used to forward the parameter to the function
  11.     template<typename F, typename... Args>
  12.     void Push(F&& f, Args&&... args) {
  13.         std::lock_guard<std::mutex> lock(mtx);
  14.         task_queue.push(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
  15.         cv.notify_one();
  16.     }
  17.     void Start() {
  18.         is_running = true;
  19.         std::thread t([this] {
  20.             while(is_running) {
  21.                 std::unique_lock<std::mutex> lock(mtx);
  22.                 cv.wait(lock, [this] { return !task_queue.empty(); });
  23.                 auto task = task_queue.front();
  24.                 task_queue.pop();
  25.                 lock.unlock();
  26.                 task();
  27.             }
  28.         });
  29.         t.detach();
  30.     }
  31.     void Stop() {
  32.         is_running = false;
  33.     }
  34. };
复制代码
  1. int main(int argc, char** argv) {
  2.     TaskQueue tq;
  3.     tq.Push(DoSomething, 1);
  4.     tq.Push(DoSomething, 2);
  5.     tq.Push(DoSomething, 3);
  6.     tq.Start();
  7.     tq.Push(DoSomething, 4);
  8.     // 等待任务结束
  9.     while(1) {
  10.         std::this_thread::sleep_for(std::chrono::seconds(1));
  11.     }
  12.     return 0;
  13. }
复制代码
实现笔记

任务队列,将需要执行的任务存储在队列中,存储的这个动作类似于生产者
当任务队列不为空时,会从队列中取出一个任务执行,当任务执行结束后再从队列取下一个,直到队列为空;
执行任务类似于消费者
基础概念理解


  • C++左值和右值
判断表达式左值还是右值的两种办法:
a. 位于赋值符号=左侧的就是左值,只能位于右侧的就是右值;需要注意的是,左值也可以当右值用;
b. 有名称、可以取到存储地址的表达式就是左值,否则就是右值;
C++右值引用(用 &&标识)
  1.   1. 和左值引用一样,右值引用也需要立即被初始化,且只能使用右值进行初始化
复制代码
  1. int num = 10;
  2. // 左值不能用于初始化右值
  3. // int &&a = num; 编译报错
  4. int &&a = 123;
复制代码
  1.   2. 和常量左值引用不同的是,右值引用可以对右值进行修改:
复制代码
[code]int num = 10;int &&ref = 12;ref = 222;// 修改右值引用的值std::cout
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

飞不高

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表