飞不高 发表于 2023-11-27 09:05:16

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

需求


[*]任务队列中可以依次添加任务;
[*]任务执行函数需要接受外部传输的参数;
[*]主动调用Start开始执行任务;
代码实现

class TaskQueue {
private:
    std::mutex mtx;
    std::condition_variable cv;
    std::queue<std::function<void()>> task_queue;
    std::atomic<bool> is_running;

public:
    TaskQueue() : is_running(false) {}
    ~TaskQueue() {}

    // std::forward is used to forward the parameter to the function
    template<typename F, typename... Args>
    void Push(F&& f, Args&&... args) {
      std::lock_guard<std::mutex> lock(mtx);
      task_queue.push(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
      cv.notify_one();
    }

    void Start() {
      is_running = true;
      std::thread t( {
            while(is_running) {
                std::unique_lock<std::mutex> lock(mtx);
                cv.wait(lock, { return !task_queue.empty(); });
                auto task = task_queue.front();
                task_queue.pop();
                lock.unlock();
                task();
            }
      });
      t.detach();
    }

    void Stop() {
      is_running = false;
    }
};int main(int argc, char** argv) {

    TaskQueue tq;
    tq.Push(DoSomething, 1);
    tq.Push(DoSomething, 2);
    tq.Push(DoSomething, 3);
    tq.Start();
    tq.Push(DoSomething, 4);

    // 等待任务结束
    while(1) {
      std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    return 0;
}实现笔记

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


[*]C++左值和右值
判断表达式左值还是右值的两种办法:
a. 位于赋值符号=左侧的就是左值,只能位于右侧的就是右值;需要注意的是,左值也可以当右值用;
b. 有名称、可以取到存储地址的表达式就是左值,否则就是右值;
C++右值引用(用 &&标识)
1. 和左值引用一样,右值引用也需要立即被初始化,且只能使用右值进行初始化int num = 10;
// 左值不能用于初始化右值
// int &&a = num; 编译报错
int &&a = 123;2. 和常量左值引用不同的是,右值引用可以对右值进行修改:int num = 10;int &&ref = 12;ref = 222;// 修改右值引用的值std::cout
页: [1]
查看完整版本: 任务队列C++实现-(完美转发)