需求
- 任务队列中可以依次添加任务;
- 任务执行函数需要接受外部传输的参数;
- 主动调用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([this] {
- while(is_running) {
- std::unique_lock<std::mutex> lock(mtx);
- cv.wait(lock, [this] { 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;
- }
复制代码 实现笔记
任务队列,将需要执行的任务存储在队列中,存储的这个动作类似于生产者;
当任务队列不为空时,会从队列中取出一个任务执行,当任务执行结束后再从队列取下一个,直到队列为空;
执行任务类似于消费者;
基础概念理解
判断表达式左值还是右值的两种办法:
a. 位于赋值符号=左侧的就是左值,只能位于右侧的就是右值;需要注意的是,左值也可以当右值用;
b. 有名称、可以取到存储地址的表达式就是左值,否则就是右值;
C++右值引用(用 &&标识)- 1. 和左值引用一样,右值引用也需要立即被初始化,且只能使用右值进行初始化
复制代码- int num = 10;
- // 左值不能用于初始化右值
- // int &&a = num; 编译报错
- int &&a = 123;
复制代码- 2. 和常量左值引用不同的是,右值引用可以对右值进行修改:
复制代码 [code]int num = 10;int &&ref = 12;ref = 222;// 修改右值引用的值std::cout |