任务队列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]