线程池 | Result、Task类
1.Task类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Task { public: Task(); ~Task() = default; void exec(); void setResult(Result* res); virtual Any run() = 0;
private: Result* result_; };
|
使用时,用户自己定义一个mytask类继承Task类,重写run方法完成自己想要的任务即可。
exec就是用来执行run()方法的一个包装函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Task::Task():result_(nullptr){}
void Task::exec() { if (result_ != nullptr) { result_->setVal(run()); } }
void Task::setResult(Result* res) { result_ = res; }
|
2.Result类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Result { public: Result(std::shared_ptr<Task> task, bool isValid = true); ~Result()=default;
void setVal(Any any);
Any get();
private: Any any_; Semaphore sem_; std::shared_ptr<Task> task_; std::atomic_bool isValid_; };
|
这个类用来接收对应task_任务结束后的返回值的,一个Task对象对应一个Result对象,Any对象作为类内成员承接具体的返回值。setVal方法是把返回值存储到Result对象的any上,get方法是用户获取task返回值的方法,就是把any的值返回给用户。
值得注意的是,加入了信号量来控制是否完成了任务,如果任务没有完成,会在get方法处阻塞,等待任务完成。
Any不支持拷贝构造所以用move来进行赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Result::Result(std::shared_ptr<Task> task, bool isValid) :isValid_(isValid),task_(task) { task_->setResult(this); }
Any Result::get() { if (!isValid_) { return ""; } sem_.wait(); return std::move(any_); }
void Result::setVal(Any any) { this->any_ = std::move(any); sem_.post(); }
|
这两者是耦合的,一个Task对应一个Result