美文网首页
线程队列模型

线程队列模型

作者: 启爻 | 来源:发表于2017-06-17 08:45 被阅读0次

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

    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();

    }

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

    相关文章

      网友评论

          本文标题:线程队列模型

          本文链接:https://www.haomeiwen.com/subject/rmyvqxtx.html