C++任务队列与多线程任务队列与多线程
摘要:
很多场合之所以使用C++,一方面是由于C++编译后的native code的高效性能,另一方面是由于C++的并发能力。并行方
式有多进程 和多线程之分,本章暂且只讨论多线程,多进程方面的知识会在其他章节具体讨论。多线程是开发C++服务器程
序非常重要的基础,如何根据需求具体的设计、分配线程以及线程间的通信,也是服务器程序非常重要的部分,除了能够带来
程序的性能提高外,若设计失误,则可能导致程序复杂而又混乱,变成bug滋生的温床。所以设计、开发的线程组件以供重
用,无论如何都是值得的。
线程相关的api并不复杂,然而无论是linux还是windows系统,都是c风格的接口,我们只需简单的封装成对象,方便易用
即可。任务队列是设计成用来进行线程间通信,使用任务队列进行线程间通信设计到一些模式,原理并不难理解,我们需要做
到是弄清楚,在什么场景下选用什么样的模式即可。
任务队列的定义:
任务队列对线程间通信进行了抽象,限定了线程间只能通过传递任务,而相关的数据及操作则被任务保存。任务队列这个
名词可能在其他场景定义过其他意义,这里讨论的任务队列定义为:能够把封装了数据和操作的任务在多线程间传递的线程安
全的先入先出的队列。其与线程关系示意图如下:
注:两个虚线框分别表示线程A和线程B恩能够访问的数据边界,由此可见 任务队列是线程间通信的媒介。
任务队列的实现:
任务的定义
生产者消费者模型在软件设计中是极其常见的模型,常常被用来实现对各个组件或系统解耦合。大到分布式的系统交互,
小到网络层对象和应用层对象的通讯,都会应用到生产者消费者模型,在任务队列中,生产和消费的对象为“任务”。这里把任
务定义为组合了数据和操作的对象,或者简单理解成包含了void (void*) 类型的函数指针和void* 数据指针的结构。我们把任务
定义成类task_t,下面来分析一下task_t的实现。
插入代码:
class task_impl_i
{
public:
virtual ~task_impl_i(){}
virtual void run() = 0;
virtual task_impl_i* fork() = 0;
};
class task_impl_t: public task_impl_i
{
public:
task_impl_t(task_func_t func_, void* arg_):
m_func(func_),
m_arg(arg_)
{}
virtual void run()
{
m_func(m_arg);
}
virtual task_impl_i* fork()
{
return new task_impl_t(m_func, m_arg);
}
protected: