Poco库异步执行框架设计与实现分析

本文详细分析了Poco库中的异步执行组件,包括TaskManager、Task和ThreadPool的使用。TaskManager用于管理Task,通过Observer模式在Task状态改变时发送通知。Task的生命周期管理在run()函数中实现,同时提供了取消任务执行的能力。Poco的Notification框架基于观察者模式,用于在任务执行过程中发送状态更新。
摘要由CSDN通过智能技术生成

Poco是一个强大的,用于构建C++程序的类库,它提供了许多非常好用的部件来帮助我们更快的开发C++应用程序,异步执行的相关部件正是这些好用的部件中的一部分。这里我们来看一下Poco库的异步执行组件的实现。

Poco库的异步执行组件主要有TaskManager,Task,ThreadPool等等。这里就主要从这些组件着手进行分析。

TaskManager/Task的使用

首先来看一下TaskManager/Task的使用

1. 要使用Poco库的TaskManager来帮我们管理异步执行的任务,我们首先需要创建一个类,也是我们的任务的抽象,继承Poco的Task类,override其中的virtual函数virtual void runTask(),并在runTask()的实现中包含我们希望去异步执行的代码。

2. 然后创建一个线程池对象ThreadPool。这一步可选。

3. 创建一个TaskManager类的对象,并将前一步创建的线程池对象传给TaskManager的构造函数。TaskManager管理的所有Task都将在这个线程池的线程中执行。如果没有为TaskManager创建单独的线程池,则所有Task都将在default的线程池中执行。

4. 创建一个Task的对象。这个Task对象应该通过operator new,在堆上创建。

5. 通过前面创建的TaskManager对象,启动执行创建的Task。在Task执行完之后,TaskManager自己会把Task对象给delete掉。

具体还是来看一下代码比较方便:

#include <iostream>

#include <Poco/TaskManager.h>
#include <Poco/Task.h>
#include <Poco/TaskNotification.h>
#include <Poco/Thread.h>
#include <Poco/ThreadPool.h>

using namespace Poco;
using namespace std;

class DemoTask : public Task {
 public:
    DemoTask();
    virtual ~DemoTask();
    virtual void runTask();
};

DemoTask::DemoTask()
        : Task("DemoTask") {
}

DemoTask::~DemoTask() {

}

void DemoTask::runTask() {
    Thread::sleep(3000);
    cout << "DemoTask runtask." << endl;
}

int main() {
	ThreadPool threadPool(2, 32);
	TaskManager taskManager(threadPool);
	DemoTask * demoTask = new DemoTask;
	taskManager.start(demoTask);
	taskManager.joinAll();
	cout << "Demo run end." << endl;
	return 0;
}

这就是使用TaskManager/Task执行异步任务的基本方法了。但TaskManager提供的功能却不只如此,它还可以在Task的状态发生改变时,通过Observer通知我们具体的用法如下:

class TaskObserver {
 public:
    TaskObserver();
    void handleTaskFinished(TaskStartedNotification *startedNotify);
    void handleTaskCancelled(TaskCancelledNotification *cancelledNotify);

    void handleTaskFinished(TaskFinishedNotification *completedNotify);

    void handleTaskFailed(TaskFailedNotification *failedNotify);
    void handleTaskProgressUpdated(TaskProgressNotification *progressNotify);
};

TaskObserver::TaskObserver() {

}

void TaskObserver::handleTaskFinished(TaskStartedNotification *startedNotify) {
    startedNotify->release();
}

void TaskObserver::handleTaskCancelled(TaskCancelledNotification *cancelledNotify) {
    cancelledNotify->release();
}

void TaskObserver::handleTaskFinished(TaskFinishedNotification *completedNotify) {
    cout << "Task finished." << endl;
    completedNotify->release();
}

void TaskObserver::handleTaskFailed(TaskFailedNotification *failedNotify) {
    failedNotify->release();
}

void TaskObserver::handleTaskProgressUpdated(TaskProgressNotification *progressNotify) {
    progressNotify->release();
}

int main() {
    ThreadPool threadPool(2, 32);
    TaskManager taskManager(threadPool);

    TaskObserver observer;
    Observer<TaskObserver, TaskFinishedNotification> finishedObserver(observer, &TaskObserver::handleTaskFinished);
    taskManager.addObserver(finishedObserver);

    DemoTask * demoTask = new DemoTask;
    taskManager.start(demoTask);

在前面那个demo的基础之上,注册observer,并接收TaskManager关于task状态变化的通知。编译运行上面的这段程序,可以看到如下的输出:

DemoTask runtask.
Task finished.
Demo run end.

这里要注意,在收到Notification,处理了事件之后,要主动地release传进来的Notification,否则会发生内存泄漏。后面我们会通过对代码的分析来更详细的了解这样做的原因。

TaskManager的实现

来看TaskManager的实现,同时也再次全面的看一下TaskManager提供的功能即接口。TaskManager这个class的定义如下:

namespace Poco {

class Notification;
class ThreadPool;
class Exception;

class Foundation_API TaskManager
/// The TaskManager manages a collection of tasks
/// and monitors their lifetime.
///
/// A TaskManager has a built-in NotificationCenter that
/// is used to send out notifications on task progress
/// and task states. See the TaskNotification class and its
/// subclasses for the various events that result in a notification.
/// To keep the number of notifications small, a TaskProgressNotification
/// will only be sent out once in 100 milliseconds.
{
 public:
    typedef AutoPtr<Task> TaskPtr;
    typedef std::list<TaskPtr> TaskList;

    TaskManager();
    /// Creates the TaskManager, using the
    /// default ThreadPool.

    TaskManager(ThreadPool& pool);
    /// Creates the TaskManager, using the
    /// given ThreadPool.

    ~TaskManager();
    /// Destroys the TaskManager.

    void start(Task* pTask);
    /// Starts the given task in a thread obtained
    /// from the thread pool.
    ///
    /// The TaskManager takes ownership of the Task object
    /// and deletes it when it it finished.

    void cancelAll();
    /// Requests cancellation of all tasks.

    void joinAll();
    /// Waits for the completion of all the threads
    /// in the TaskManager's thread pool.
    ///
    /// Note: joinAll() will wait for ALL tasks in the
    /// TaskManager's ThreadPool to complete. If the
    /// ThreadPool has threads created by other
    /// facilities, these threads must also complete
    /// before joinAll() can return.

    TaskList taskList() const;
    /// Returns a copy of the internal task list.

    int count() const;
    /// Returns the number of tasks in the internal task list.

    void addObserver(const AbstractObserver& observer);
    /// Registers an observer with the NotificationCenter.
    /// Usage:
    ///     Observer<MyClass, MyNotification> obs(*this, &MyClass::handleNotification);
    ///     notificationCenter.addObserver(obs);

    void removeObserver(const AbstractObserver& observer);
    /// Unregisters an observer with the NotificationCenter.

    static const int MIN_PROGRESS_NOTIFICATION_INTERVAL;

 protected:
    void postNotification(const Notification::Ptr& pNf);
    /// Posts a notification to the task manager's
    /// notification center.

    void taskStarted(Task* pTask);
    void taskProgress(Task* pTask, float progress);
    void taskCancelled(Task* pTask);
    void taskFinished(Task* pTask);
    void taskFailed(Task* pTask, const Exception& exc);

 private:
    ThreadPool& _threadPool;
    TaskList _taskList;
    Timestamp _lastProgressNotification;
    NotificationCenter _nc;
    mutable FastMutex _mutex;

    fr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值