C多线程编程总结
在开发C程序时,一般在吞吐量、并发、实时性上有较高的要求。设计C程序时,总结起来可以从如下几点提高效率:
l并发l异步l缓存
下面将我平常工作中遇到一些问题例举一二,其设计思想无非以上三点。
1任务队列
11以生产者消费者模型设计任务队列
生产者消费者模型是人们非常熟悉的模型,比如在某个服务器程序中,User数据被当逻辑模块修改后,就产生一个更新数据库的任务(produce),投递给IO模块任务队列,IO模块从任务队列中取出任务执行sql操作(co
sume)。设计通用的任务队列,示例代码如下:详细实现可参见:httpffow
googlecodecomsv
tru
kfflibi
cludedetailtask_queue_implh
voidtask_queue_tproduceco
sttask_ttask_lock_guard_tlockm_mutexifm_tasklistempty条件满足唤醒等待线程m_co
dsig
alm_tasklistpush_backtask_i
ttask_queue_tcomsumetask_ttask_lock_guard_tlockm_mutexwhilem_tasklistempty当没有作业时,就等待直到条件满足被唤醒iffalsem_flagretur
1m_co
dwaittask_m_tasklistfro
tm_tasklistpop_fro
tretur
0
12
任务队列使用技巧
f121IO与逻辑分离比如网络游戏服务器程序中,网络模块收到消息包,投递给逻辑层后立即返回,继续接受下一个消息包。逻辑线程在一个没有io操作的环境下运行,以保障实时性。示例:
voidha
dle_xx_msglo
guidco
stxx_msg_tmsglogic_task_queuepostboostbi
dservie_tprocesuidmsg
注意,此模式下为单任务队列,每个任务队列单线程。122并行流水线上面的只是完成了io和cpu运算的并行,cpu中逻辑操作是串行的。而在某些场合,cpu逻辑运算部分也可实现并行,如游戏中用户A种菜和B种菜两种操作是完全可以并行的,因为两个操作没有共享数据。最简单的方式是A、B相关的操作被分配到不同的任务队列中。示例如下:
voidha
dle_xx_msglo
guidco
stxx_msg_tmsglogic_task_queue_arrayuidsizeoflogic_task_queue_arraypostboostbi
dservie_tprocesuidmsg
注意,此模式下为多任务队列,每个任务队列单线程。123连接池与异步回调比如逻辑Service模块需要数据库模块异步载入用户数据,并做后续处理计算。而数据库模块拥有一个固定连接数的连接池,当执行SQL的任务到来时,选择一个空闲的连接,执行SQL,并把SQL通过回调函数传递给逻辑层。其步骤如下:
预先分配好线程池,每个线程创建一个连接到数据库的连接
为数据库模块创建一个任务队列,所有线程都是这个任务队列的消费者
逻辑层想数据库模块r