fd

XDL 的网络流程

时间秒杀一切 提交于 2020-01-10 14:18:40
在xdl中会在每个核心运行SeastarServer::Start函数(函数代码位于https://github.com/alibaba/x-deeplearning/blob/master/xdl/third_party/seastar/service/server.cc,22行。 void SeastarServer::Start() { seastar::listen_options lo; lo.reuse_address = true; mListener = seastar::engine().listen(seastar::make_ipv4_address({mPort}), lo); // Poll() will be start in reactor //seastar::engine().GetQueuePoller().Poll(); // accept and read seastar::keep_doing([this] { return mListener->accept().then_wrapped([this] (auto&& f) mutable { try { std::tuple<seastar::connected_socket, seastar::socket_address> data = f.get(); seastar:

libevent中的bufferevent原理

你离开我真会死。 提交于 2020-01-10 03:27:14
以前的文章看过缓冲区buffer了,libevent用bufferevent来负责管理缓冲区与buffer读写事件。 今天就带大家看下evbuffer.c,使用bufferevent处理事件的数据,是buffer和event的综合。在最后用一个稍微综合的例子看下使用bufferevent的整个流程。   首先依旧看下bufferevent的结构。结构很清晰。源码版本1.4.14。    1 struct bufferevent { 2 struct event_base *ev_base; 3 4 //读事件 5 struct event ev_read; 6 //写事件 7 struct event ev_write; 8 //读缓冲区,输入缓冲 9 struct evbuffer *input; 10 //写缓冲区,输出缓冲 11 struct evbuffer *output; 12 13 //读水位 14 struct event_watermark wm_read; 15 //写水位 16 struct event_watermark wm_write; 17 18 //发生读触发用户设置的回调 19 evbuffercb readcb; 20 //发生写触发用户设置的回调 21 evbuffercb writecb; 22 //发生错误触发用户设置的回调 23

进程通信之对象-无名管道

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-10 00:06:34
无名管道(管道=队列):在系统中无不存在这样一个文件名 例子1:用pipe()函数创建一个无名管道,实现一个进程向管道中读写信息;建立no_name_pipe1.c内容如下 #include"unistd.h" #include"sdtio.h" #include"stdlib.h" #include"string.h" int main() { int fd[2]; int ret;//管道描述符 char write_buf[]="hellolinux!";//要向管道写入的信息 char read_buf[128]={0};//读缓存 ret=pipe(); if(ret<0) { printf("create a pipe failure\n"); return -1; } printf("create pipe succcess 写端fd[1]=%d ,读端fd[0]=%d\n",fd[1],fd[0]); //向管道写入信息 write(fd[1],write_buf,sizeof(write_buf)); //start read from pipe read(fd[0],read_buf,128); printf("read_buf=%s\n",read_buf); //关闭管道两端 close(fd[0]); close(fd[1]); return 0; }

Redis 单线程却能支撑高并发 - 简书 https://www.jianshu.com/p/2d293482f272

时间秒杀一切 提交于 2020-01-09 18:14:33
小结: 1、 在 I/O 多路复用模型中,最重要的函数调用就是 select,该方法的能够同时监控多个文件描述符的可读可写情况; 2、 Redis 服务采用 Reactor 的方式来实现文件事件处理器(每一个网络连接其实都对应一个文件描述符); 3、 虽然整个文件事件处理器是在单线程上运行的,但是通过 I/O 多路复用模块的引入,实现了同时对多个 FD 读写的监控,提高了网络通信模型的性能,同时也可以保证整个 Redis 服务实现的简单 4、 Redis 会优先选择时间复杂度为 O(1) 的 I/O 多路复用函数作为底层实现,包括 Solaries 10 中的 evport、Linux 中的 epoll 和 macOS/FreeBSD 中的 kqueue,上述的这些函数都使用了内核内部的结构,并且能够服务几十万的文件描述符。 但是如果当前编译环境没有上述函数,就会选择 select 作为备选方案,由于其在使用时会扫描全部监听的描述符,所以其时间复杂度较差 O(n),并且只能同时服务 1024 个文件描述符,所以一般并不会以 select 作为第一方案使用。 https://mp.weixin.qq.com/s/ySG2Qtitr6b8Zcb-SAMnGQ Redis 和 I/O 多路复用 https://draveness.me/redis-io-multiplexing

C基础 带你手写 redis ae 事件驱动模型

五迷三道 提交于 2020-01-08 23:13:45
引言 - 整体认识   redis ae 事件驱动模型, 网上聊得很多. 但当你仔细看完一篇又一篇之后, 可能你看的很舒服, 但对于 作者为什么要这么写, 出发点, 好处, 缺点 ... 可能还是好模糊, 不是吗? 我们这里基于阅读的人已经了解了 IO 复用大致流程且抄写过 ae 的全部代码. 好, 那开始吧, 希望后面的 点拨, 给同学们醍醐灌顶一下.   先看看 ae.h 设计 /* A simple event-driven programming library. Originally I wrote this code * for the Jim's event-loop (Jim is a Tcl interpreter) but later translated * it in form of a library for easy reuse. * * Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that

epoll中的LT和ET读写方式

三世轮回 提交于 2020-01-07 15:11:43
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 可读可写状态 1. 下列四个条件中的任何一个满足时,一个套接口准备好读: a. 该套接口接收缓冲区中的数据字节数 大等于 套接口接收缓冲区的低潮标记,对于 TCP 和 UDP 而言,其缺省值为 1 ; b. 该连接的读这一半关闭,对这样的套接口的读操作将不阻塞并返回 0 ; c. 该套接口是一个监听套接口且已完成的连接数不为 0 ;(就是 accept 成功返回 ) d. 其上有一个套接口错误等待处理,对这样的套接口的读操作将不阻塞并返回 -1 ; 2. 下列四个条件中的任何一个满足时,一个套接口准备好写: a. 该套接口发送缓冲区中的可用空间字节数 大等于 套接口发送缓冲区的低潮标记,对于 TCP 和 UDP 而言,其缺省值为 2048 ; b. 该连接的写这一半关闭,对这样的套接口的写操作将产生 SIGPIPE 信号; c. 该套接口早先使用非阻塞式 connect 以建立连接,并且连接已经异步建立,或者 connect 以失败告终; d. 其上有一个套接口错误等待处理,对这样的套接口的写操作将不阻塞并返回 -1 ; 3.select 与非阻塞 connect 一起使用的时候有以下两个注意点:( 1 )当连接成功建立时,描述字变为可写;( 2 )当连接建立遇到错误时,描述字变为既可读又可写;

ThinkPHP5结合Swoole开发实现WebSocket在线聊天

社会主义新天地 提交于 2020-01-07 08:16:22
ThinkPHP使用Swoole需要安装 think-swoole Composer包,前提系统已经安装好了Swoole PECL 拓展 在tp5的项目根目录下执行composer命令安装think-swoole: composer require topthink/think-swoole 安装成功: 代码如下 新建WebSocket.php控制器: 监听端口要确认服务器放行,宝塔环境还需要添加安全组规则 <?php namespace app\home\controller; use think\swoole\Server; class WebSocket extends Server { protected $host = '0.0.0.0'; //监听所有地址 protected $port = 9501; //监听9501端口 protected $serverType = 'socket'; protected $option = [ 'worker_num'=> 4, //设置启动的Worker进程数 'daemonize' => false, //守护进程化(上线改为true) 'backlog' => 128, //Listen队列长度 'dispatch_mode' => 2, //固定模式,保证同一个连接发来的数据只会被同一个worker处理 //心跳检测

惊群问题的思考

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-07 06:09:58
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 原文: http://www.cppblog.com/isware/archive/2011/07/20/151470.aspx “据说”惊群问题已经是一个很古老的问题了,并且在大多数系统中 已经得到有效解决 ,但对我来说,仍旧是一个比较新的概念,因此有必要记录一下。 什么是惊群 举一个很简单的例子,当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到食物的鸽子只好回去继续睡觉,等待下一块食物到来。这样,每扔一块食物,都会惊动所有的鸽子,即为惊群。对于操作系统来说,多个进程/线程在等待同一资源是,也会产生类似的效果,其结果就是每当资源可用,所有的进程/线程都来竞争资源,造成的后果: 1)系统对用户进程/线程频繁的做无效的调度、上下文切换,系统系能大打折扣。 2)为了确保只有一个线程得到资源,用户必须对资源操作进行加锁保护,进一步加大了系统开销。 最常见的例子就是对于socket描述符的accept操作,当多个用户进程/线程监听在同一个端口上时,由于实际只可能accept一次,因此就会产生惊群现象,当然前面已经说过了,这个问题是一个古老的问题,新的操作系统内核已经解决了这一问题。 linux内核解决惊群问题的方法 对于一些已知的惊群问题,内核开发者增加了一个“互斥等待

记一次传递文件句柄引发的血案 (续)

风流意气都作罢 提交于 2020-01-06 17:38:12
继 记一次传递文件句柄引发的血案 之后,这个 demo 又引发了一次血案,现录如下。 这次我是在 linux 上测试文件句柄的传递,linux 上并没有 STREAMS 系统, 因此是采用 unix domain socket 的 sendmsg/recvmsg 中控制消息部分来传递句柄的。 代码的主要修改部分集中于发送 fd 与接收 fd 处,一开始代码是这样的,运行良好。 spipe_fd.c 1 #define MAXLINE 128 2 #define RIGHTSLEN CMSG_LEN(sizeof(int)) 3 #define CREDSLEN CMSG_LEN(sizeof(struct CREDSTRUCT)) 4 #define CONTROLLEN (RIGHTSLEN+CREDSLEN) 5 6 int send_fd (int fd, int fd_to_send) 7 { 8 struct iovec iov[1]; 9 struct msghdr msg; 10 struct cmsghdr *cmptr = NULL; 11 char buf[2]; 12 13 iov[0].iov_base = buf; 14 iov[0].iov_len = 2; 15 16 msg.msg_iov = iov; 17 msg.msg_iovlen = 1;

C语言使用多进程实现高并发tcp服务器

蹲街弑〆低调 提交于 2020-01-06 16:40:37
多进程并发服务器的流程 socket; 创建监听套接字 bind; 绑定地址结构 listen(); 设置监听上限 accept();进行循环监听 fork();接收到客户端请求创建新的进程 close(); 与客户端通讯的套接字关闭 实现C语言并发服务器 #include <stdio.h> #include <apra/inet.h> #include <errno.h> #include <sys/socket.h> #include <unistd.h> #include <signal.h> void perr_exit(const char *s){ perror(s); exit(-1); } int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr) { int n; again: if((n = accept(fd,sa,salenptr))<0){ if((errno == ECONNABORTED) || errno == EINTR) goto again; else perr_exit("accept error"); } return n; } int Bind(int fd, struct sockaddr *sa, socklen_t salen) { int n; if ((n =