epoll

对Redis 单进程、单线程模型的理解(网摘)

巧了我就是萌 提交于 2019-12-09 11:42:34
1、基本原理 采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗) (1)为什么不采用多进程或多线程处理? 多线程处理可能涉及到锁 多线程处理会涉及到线程切换而消耗CPU (2)单线程处理的缺点? 无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善 2、Redis不存在线程安全问题? Redis采用了线程封闭的方式,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个redis操作的复合操作来说,依然需要锁,而且有可能是分布式锁 3、什么是多路I/O复用(Epoll) (1) 网络IO都是通过Socket实现,Server在某一个端口持续监听,客户端通过Socket(IP+Port)与服务器建立连接(ServerSocket.accept),成功建立连接之后,就可以使用Socket中封装的InputStream和OutputStream进行IO交互了。针对每个客户端,Server都会创建一个新线程专门用于处理 (2) 默认情况下,网络IO是阻塞模式,即服务器线程在数据到来之前处于【阻塞】状态,等到数据到达,会自动唤醒服务器线程,着手进行处理。阻塞模式下,一个线程只能处理一个流的IO事件 (3) 为了提升服务器线程处理效率,有以下三种思路 (1)非阻塞【忙轮询】:采用死循环方式轮询每一个流,如果有IO事件就处理

How epoll detect clientside close in Python?

拥有回忆 提交于 2019-12-09 04:27:16
问题 Here is my server """Server using epoll method""" import os import select import socket import time from oodict import OODict addr = ('localhost', 8989) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(addr) s.listen(8) s.setblocking(0) # Non blocking socket server epoll = select.epoll() epoll.register(s.fileno(), select.EPOLLIN) # Level triggerred cs = {} data = '' while True: time.sleep(1) events = epoll.poll(1) # Timeout 1

How to use the epoll/kqueue enabled version of GHC/Haskell for network connections?

痞子三分冷 提交于 2019-12-08 04:52:27
There is a lot of old information on the net regarding an epoll/kqueue enabled GHC. For example, the code on the Simple Servers wiki page doesn't compile anymore. Could someone provide a basic example of how to use this feature with a modern GHC version to build, e.g. a TCP server that just responds with "Hello" on connect? GHC's IO manager uses epoll/kqueue under the hood without any special programmer effort. Just write the naive threaded program -- that puts each concurrent blocking IO call in a separate thread -- and GHC will make sure it works out the way you want it to. 来源: https:/

unix accept() function returns the same file descriptor twice

限于喜欢 提交于 2019-12-08 03:40:15
问题 I have a problem with my multithreaded networking server program. I have a main thread that is listening for new client connections. I use Linux epoll to get I/O event notifications. For each incoming event, I create a thread that accept() the new connection and assign a fd to it. Under heavy loading, it can occur that the same fd is assigned twice causing my program to crash. My question is: how can the system re-assign a fd that is still used by another thread? Thanks, 回答1: Presumably there

Question about epoll and splice

不想你离开。 提交于 2019-12-07 18:15:35
问题 My application is going to send huge amount of data over network, so I decided (because I'm using Linux) to use epoll and splice. Here's how I see it (pseudocode): epoll_ctl (file_fd, EPOLL_CTL_ADD); // waiting for EPOLLIN event while(1) { epoll_wait (tmp_structure); if (tmp_structure->fd == file_descriptor) { epoll_ctl (file_fd, EPOLL_CTL_DEL); epoll_ctl (tcp_socket_fd, EPOLL_CTL_ADD); // wait for EPOLLOUT event } if (tmp_structure->fd == tcp_socket_descriptor) { splice (file_fd, tcp_socket

epoll vs select for very small number of connections

点点圈 提交于 2019-12-07 14:13:59
问题 I have been using select to handle connections, recently there was a change an our socket library and select was replaced by epoll for linux platform. my application architecture is such that I make only one or at max 2 socket connections and epoll/select on them in a single thread. now with recent switch to epoll i noticed that performance of application has diminshed, I was actually surprised and was expecting performance go up or reamin same. I tried looking at various other parts and this

Linux 五种IO模型

梦想的初衷 提交于 2019-12-07 13:54:16
1,什么是IO模型 IO 在计算机中指的就是 Input/Output (输入/输出)。 Input/Output (输入/输出)的内容当然就是 data (数据)了。 那么数据被 Input 到哪, Output 到哪呢? Input (输入)数据到内存中, Output (输出)数据到 IO 设备(磁盘、网络等需要与内存进行数据交互的设备)中; IO 设备与内存直接的数据传输通过 IO 接口,操作系统封装了 IO 接口,我们编程时可以直接使用。 网络IO的本质是socket的读取,socket在linux系统被抽象为流,IO可以理解为对流的操作。 对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。所以说, 当一个read操作发生时,它会经历两个阶段: 等待数据准备 (Waiting for the data to be ready)。 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)。 对于socket流而言, 第一步:通常涉及等待网络上的数据分组到达,然后被复制到内核的某个缓冲区。 第二步:把数据从内核缓冲区复制到应用进程缓冲区。 网络应用需要处理的无非就是两大类问题, 网络IO,数据计算 。相对于后者,网络IO的延迟

Linux 五种IO模型

社会主义新天地 提交于 2019-12-07 13:38:48
1,什么是IO模型 IO 在计算机中指的就是 Input/Output (输入/输出)。 Input/Output (输入/输出)的内容当然就是 data (数据)了。 那么数据被 Input 到哪, Output 到哪呢? Input (输入)数据到内存中, Output (输出)数据到 IO 设备(磁盘、网络等需要与内存进行数据交互的设备)中; IO 设备与内存直接的数据传输通过 IO 接口,操作系统封装了 IO 接口,我们编程时可以直接使用。 网络IO的本质是socket的读取,socket在linux系统被抽象为流,IO可以理解为对流的操作。 对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。所以说, 当一个read操作发生时,它会经历两个阶段: 等待数据准备 (Waiting for the data to be ready)。 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)。 对于socket流而言, 第一步:通常涉及等待网络上的数据分组到达,然后被复制到内核的某个缓冲区。 第二步:把数据从内核缓冲区复制到应用进程缓冲区。 网络应用需要处理的无非就是两大类问题, 网络IO,数据计算 。相对于后者,网络IO的延迟

Is it efficient to use epoll with devices (/dev/event/…)?

隐身守侯 提交于 2019-12-07 05:30:25
问题 I am working on a monothreaded process applet which creates a proxy virtual device (more precisely a virtual Xbox 360 pad); I do manage to create it with the uinput interface, I set it up properly and it works just fine. In order to feed commands to this virtual device , I read events from another real interface (in this case a PS3 pad), and I open the real device file with these flags: fd = open("/dev/input/event22", O_RDONLY); // open the PS3 pad The main loop is something like (minus error

Libevent源码分析-----配置event_base

▼魔方 西西 提交于 2019-12-07 03:17:24
前面的博文都是讲一些Libevent的一些辅助结构,现在来讲一下关键结构体:event_base。 这里作一个提醒,在阅读Libevent源码时,会经常看到backend这个单词。其直译是“后端”。实际上其指的是Libevent内部使用的多路IO复用函数,多路IO复用函数就是select、poll、epoll这类函数。本系列博文中,为了叙述方便,“多路IO复用函数”与“后端”这两种说法都会采用。 配置结构体: 通常我们获取event_base都是通过event_base_new()这个无参函数。使用这个无参函数,只能得到一个默认配置的event_base结构体。本文主要是讲一些怎么获取一个非默认配置的event_base以及可以对event_base进行哪些配置。 还是先看一下event_base_new函数吧。 //event.c文件 struct event_base * event_base_new(void) { struct event_base *base = NULL; struct event_config *cfg = event_config_new(); if (cfg) { base = event_base_new_with_config(cfg); event_config_free(cfg); } return base; } 可以看到