线程队列模型

刚入公司那会,第一次接触到队列模型,倍感神奇:一个无限循环,加一个条件判断阻塞函数,再加各个队列处理函数,就是整个模型代码的全部,代码形式如下。

for(;;)

{

    condition_wait();

    scan_que_1();

    scan_que_2();

    ...

}

暂且称上面这个模型为初级模型,优点只是简单粗暴,缺点有很多:其一,当要处理的队列很多时,condition_wait判断复杂,稍有不慎就真死循环了;其二效率比较低,当只有一个队列有任务时,也需要扫描所有队列。

之后接触了eventfd+epoll_fd的模型,对初级模型进行了改进,进化到了中级模型,基本原理比较简单:每个队列关联一个eventfd和一个处理方法;每个线程关联一个epoll_fd;初始化的时候将队列的eventfd添加到epoll_fd监听表中;队列有任务时对eventfd执行写操作,唤醒epoll处理事件,从事件中取出并调用队列处理方法。中级模型的代码形式如下(epoll模型可以百度一下,很多资料)。

队列注册:

register()

{

    que.fd    = eventfd();

    que.func = scan_que_1;

    epoll_add(thread.fd,que.fd,&que);

}

线程主体

thread_func()

{

    thread.fd = epoll_create();

    for(;;)

    {

        epoll_wait();

        que = get_que_from_epoll();

        que.func();

    }

}

中级模型的优点在于将条件等待过程抽象为简单的epoll模型,避免了条件复杂化,同时提高了处理效率,只有有任务的队列才会被处理。中级模型的缺点在于队列有方法(业务队列),在队列很多的时候,需要写大量的重复代码(注册过程),很自然的一个想法是队列是公共的,但队列中的任务带方法,这就是高级模型,代码形式如下。

业务过程:

thread.que.add_job(args,work_func);

公共队列:

add_job(args,work_func)

{

    que_event.args = args;

    que_event.func = work_func;

    que.insert(&que_event);

}

handle()

{

    event = get_event_from_que();

    event.func(event.args);

}

线程主体:

thread.fd = epoll_create();

thread.que = comm_que();

epoll_add(thread.que.fd);

for(;;)

{

    epoll_wait();

    que.hander();

}

业务函数在线程,即是初级模型;业务函数在队列,中级模型;队列事件有业务,高级模型。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容