ZLMediaKit中多线程

6 篇文章 1 订阅
4 篇文章 0 订阅

ZLMediaKit中多线程

  • main函数中,一下语句是设置线程池中的线程个数
 //设置poller线程数,该函数必须在使用ZLToolKit网络相关对象之前调用才能生效
 EventPollerPool::setPoolSize(threads);
  • 在main中创建了很多的TcpServer,其构造函数如下,其中会初始化当前TcpServer对象的** _poller**成员。其中 EventPollerPool::Instance()会返回一个静态的EventPollerPool对象
  • 对于后续的EventPollerPool::Instance().getPoller(),由于TcpServer当前的线程不同于线程池中的任何一个线程,所以,auto poller = EventPoller::getCurrentPoller();获取为空,最后是走的语句return dynamic_pointer_cast<EventPoller>(getExecutor()),此语句就是从线程池中获取一个负载最小的线程
EventPoller::Ptr EventPollerPool::getPoller(){
    auto poller = EventPoller::getCurrentPoller();
    if(_preferCurrentThread && poller){
        return poller;
    }
    return dynamic_pointer_cast<EventPoller>(getExecutor());
}
TcpServer(const EventPoller::Ptr &poller = nullptr) {
        setOnCreateSocket(nullptr);          //设置createSocket函数
        _poller = poller ? poller : EventPollerPool::Instance().getPoller();
        _socket = createSocket();
        _socket->setOnAccept(bind(&TcpServer::onAcceptConnection_l, this, placeholders::_1));
        _socket->setOnBeforeAccept(bind(&TcpServer::onBeforeAcceptConnection_l, this, std::placeholders::_1));
    }
  • 接下来是_socket = createSocket(),就是对socket对象进行了一些初始化,后续还设置了socket的两个回调函数。
Socket::Ptr Socket::createSocket(const EventPoller::Ptr &poller, bool enable_mutex){
    return Socket::Ptr(new Socket(poller, enable_mutex));
}

Socket::Socket(const EventPoller::Ptr &poller, bool enable_mutex) :
        _mtx_sock_fd(enable_mutex), _mtx_event(enable_mutex),
        _mtx_send_buf_waiting(enable_mutex), _mtx_send_buf_sending(enable_mutex){

    _poller = poller;
    if (!_poller) {
        _poller = EventPollerPool::Instance().getPoller();
    }
    setOnRead(nullptr);
    setOnErr(nullptr);
    setOnAccept(nullptr);
    setOnFlush(nullptr);
    setOnBeforeAccept(nullptr);
}
  • 构造看完了之后,我们接下来看其的调用 start,在start里面创建了socket(epoll),并将socket添加到poller的监听事件中。并将此socket添加到其他的线程中进行监听
    监听事件中
    template<typename SessionType>
    void start_l(uint16_t port, const std::string &host = "0.0.0.0", uint32_t backlog = 1024) {
        //TcpSession创建器,通过它创建不同类型的服务器
        _session_alloc = [](const TcpServer::Ptr &server, const Socket::Ptr &sock) {
            auto session = std::make_shared<SessionType>(sock);
            session->setOnCreateSocket(server->_on_create_socket);
            return std::make_shared<TcpSessionHelper>(server, session);
        };

        //创建socket并将socket添加到poller的监听事件里面
        if (!_socket->listen(port, host.c_str(), backlog)) {
            //创建tcp监听失败,可能是由于端口占用或权限问题
            string err = (StrPrinter << "listen on " << host << ":" << port << " failed:" << get_uv_errmsg(true));
            throw std::runtime_error(err);
        }

        //新建一个定时器定时管理这些tcp会话
        weak_ptr<TcpServer> weak_self = shared_from_this();

        //2秒重复执行一下 onManagerSession  遍历每个session(链接)是否超时  超时就断开
        _timer = std::make_shared<Timer>(2.0f, [weak_self]() -> bool {
            auto strong_self = weak_self.lock();
            if (!strong_self) {
                return false;
            }
            strong_self->onManagerSession();
            return true;
        }, _poller);
        InfoL << "TCP Server listening on " << host << ":" << port;
    }
    template <typename SessionType>
    void start(uint16_t port, const std::string &host = "0.0.0.0", uint32_t backlog = 1024) {

        start_l<SessionType>(port, host, backlog);

       //一个线程有一个TaskExecutor,现在是用这个函数处理每个 TaskExecutor
        EventPollerPool::Instance().for_each([&](const TaskExecutor::Ptr &executor) {
            EventPoller::Ptr poller = dynamic_pointer_cast<EventPoller>(executor);
            if (poller == _poller || !poller) {
                return;
            }
            
            //如果除来本TcpServer的poller还有其他的poller,
            //则使用其他的poller创建本TcpSever的克隆版本,让其他poller也监听当前的socket
            auto &serverRef = _cloned_server[poller.get()];
            if (!serverRef) {
                serverRef = onCreatServer(poller);
            }
            if (serverRef) {
                serverRef->cloneFrom(*this);
            }
        });

    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值