美文网首页
多线程服务器的常见编程模型

多线程服务器的常见编程模型

作者: CP3fans | 来源:发表于2020-09-21 08:53 被阅读0次

多线程服务器的常见编程模型

IO Models

image

A ->[tcp send buffer] --->[tcp recv buffer]-> B

Blocking IO : A send data 发送缓冲区满或 B recv data接收缓冲区空 会阻塞当前线程

NonBlocking IO: 和Blocking IO不同的是,send或者recv直接返回错误(需要轮询调用)

IO Multiplexing:通过Select/Poll/Epoll等系统调用监控多个连接上的读写事件

Thread Models

Blocking IO + One Thread Per Connection

  • Acceptor -> [New Thread]
  • 频繁创建销毁线程的时间开销,线程之间的切换也会有大量开销
  • 创建大量线程会消耗完系统内存

Blocking IO + Thread Pool (Tomcat BIO)

  • Acceptor -> worker thread pool
  • 适合短连接,并发数有限

IO Multiplexing + Thread Pool (Tomcat NIO)

  • Acceptor->[event queue]->Poller(select/poll/epoll)->worker(one of Thread Pool)

IO Multiplexing + One Thread One Loop *

  • 线程数目基本固定
  • 高并发

One Thread One Loop思想

一个线程一个循环流程

Loop结构

void CReactor::Run()
{
    //线程退出标志
    m_bShouldRun = true;
    while(m_bShouldRun)
    {
        //处理其他的任务
        handle_other_task();
        //利用select/pool/epoll等I/O多路复用监听各个连接(fd)的读写事件
        select_or_epoll_function();
        //处理各个连接(fd)的读写事件
        handle_io_event();
        //处理定时器
                check_timer();
        //处理同步或者异步事件
        dispatch_event();
    }
}

线程分工(front)

front线程交互

AcceptReactor

1、监听是否有新的客户端连接(Listenfd上是否有读事件发生)。

2、有新连接则生成新连接的socket(clientfd),并将该socket传递给frontReactor。

Q:线程之间如何传递?

SendEvent Or PostEvent

Q:新连接分配策略?

Round Robin(轮询) 缺点:负载均衡有点问题

TresultReactor

1、订阅tserver发布的流水,接收到流水中的XTP报文,存到TradeResult(CachedFlow)中。

FrontReactor

1、通过Epoll或者Select系统调用监听该线程所负责Socket连接上的读写事件

2、收包(收网络数据,放缓冲区,解包并处理) 发包(....)

3、从TradeResult(cachedFlow)中读取从tserver发布的XTP报文,并处理。

Q:TresultReactor放到TradeResult流中数据,怎么及时让FrontReactor来处理呢?(效率问题)

    int nfds = epoll_wait(m_fdEpoll, events, EPOLL_MAX_EVENTS, timeout);

1、timeout设置为0

如果handleothertask没有事做,同时socket没有IO读写事情,线程空转,浪费CPU时间片。

2、timeout设置为10ms

如果没有网络IO时间发生,epoll_wait需要挂起timeout时间才能返回,这样当有其他任务发生,handle_other_task()就会延时处理,TradeResultFlow交易结果流中的数据,frontReactor不能及时处理。

解决方案:

创建eventfd(唤醒fd),并把eventfd绑定到epollfd中,当我们想唤醒直接去执行handle_other_task()时,往eventfd中写入一个字节,该eventfd就变成可读,epoll_wait就立马返回,接下来就可以处理handle_other_task()里面的任务了。

相关文章

  • golang的线程模型——GMP模型

    常见的线程模型 单线程服务器编程模型:Redis、Node.、JavaScript 多线程服务器编程模型:并发多个...

  • 多线程服务器的常见编程模型

    多线程服务器的常见编程模型 IO Models A ->[tcp send buffer] --->[tcp re...

  • 原子类型与原子操作

    原子类型和原子操作 并行编程、多线程与C++11 常见的并行编程有多种模型:共享内存、多线程、消息传递等。 多线程...

  • IO模型

    服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(BlockingIO):即传...

  • 高性能IO模型(摘选)

    高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Bloc...

  • IO多路复用机制详解

    高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Bloc...

  • Netty教程-IO多路复用机制详解

    高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Bloc...

  • java内存模型

    前言 在学习java多线程并发编程前,必须要了解java内存模型,只有了解java内存模型,才能知道为什么多线程并...

  • 11.1-全栈Java笔记:多线程技术的基本概念

    多线程是JAVA语言的重要特性,大量应用于网络编程、应用于服务器端程序的开发、以及最常见的UI界面底层原理、操作系...

  • 11.1-全栈Java笔记:多线程技术的基本概念

    多线程是JAVA语言的重要特性,大量应用于网络编程、应用于服务器端程序的开发、以及最常见的UI界面底层原理、操作系...

网友评论

      本文标题:多线程服务器的常见编程模型

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