可串行 线程池

基本的线程池如下图所示:

         线程池的原理类似一个生产者-消费者的模式。生产者(一般是主线程/IO线程 )将执行函数指针和要传递给函数的参数打包,然后放到任务队列里面;消费者(线程group) 从任务队列中取出任务,得到要执行的函数指针和函数参数,调用函数指针执行任务。执行完之后继续从任务队列里面获取任务。

 

 

 

线程池最大的优点就是多个任务并行执行,但不保证任务执行的顺序。但是在某些环境下,任务队列中的任务会划分成若干子集,每个子集内部需要严格按照顺序执行;但是不同的子集可以并行执行。

    例如将多条日志保存到不同的文件:保存到同一个文件的日志有着严格的先后顺序,需要串行写入;但是不同文件之间的日志可以并行写入。

    为了满足上述需求,笔者最近开发了一个特殊的线城市----可串行线程池。大概架构如下图所示:

   

除了维护任务队列之外,还维护了一个运行队列,保存线程group中正在执行的任务。每次取任务时,先判断改任务是否可以与运行队列中的任务并行执行,如果不可以,则暂时不取出该任务,继续判断下一个,直到成功取出任务。

     基本接口如下:

//任务结构体
typedef struct {
    void (*function)(void *);//任务执行函数
    void *argument;//function 参数
	void (*freer)(void *);//argument 惰性释放函数
} task_t;


//创建线程池
threadpool_t *threadpool_create(int thread_count, int queue_size, int flags);


//回调函数类型,用于检查两个任务是否可以并行执行
typedef  bool check_func(const threadpool_task_t *t1,const threadpool_task_t *t2);
//设置回调函数
int threadpool_set_concurrence_check(threadpool_t *pool,check_func *checker);






//添加任务 pool:线程池  routine:线程回调函数   arg:要传给routine的参数
//释放或delete arg的函数
//因为要在 check_func 中用到arg ,所以在routine不应该是否arg,而由线程池惰性释放
int threadpool_add(threadpool_t *pool, void (*routine)(void *),
                   void *arg, void (*free)(void *) );

 

具体代码参见我的git

https://github.com/sunwake/serializable_thread_pool

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值