epoll_create 创建的 文件描述符和其他文件描述符一样,是被fork出的子进程继承的,那也就是子进程可以使用这个epoll fd添加感兴趣的io(epoll_ctl),然后是可以影响到父进程的epoll_wait。比如,子进程中注册了一个io写事件后,因为某种原因挂起来了,导致父进程的epoll_wait频繁返回,CPU占用率飙升。看下下面的演示代码:

    void DoWrite(int epollfd) {
  5     int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
  6     if (fd < 0) {
  7         perror("socket ");
  8         exit(-1);
  9     }
10     struct sockaddr_un peer_addr;
11     memset(&peer_addr, 0, sizeof(peer_addr));
12     peer_addr.sun_family = AF_LOCAL;
13     const char *ipc_path =  "/home/longzhiri/my_code/nettest/localnettest.ipc";
14     strncpy(peer_addr.sun_path, ipc_path, sizeof(peer_addr.sun_path)-1);
15     if (connect(fd, (struct sockaddr *)&peer_addr,  SUN_LEN(&peer_addr))<0){
16         perror("connect ");
17         exit(-1);
18     }
19     struct epoll_event ev, events[10];
20     ev.events = EPOLLOUT;
21     ev.data.fd = fd;
22     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) < 0) {
23         perror("epoll_ctl");
24         exit(-1);
25     }
26
27     sleep(10);
28     epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev);
29     printf("child process exit\n");
30 }
31
32 int main(int argc, char *argv[]) {
33     int epollfd = epoll_create(10);
34     if (epollfd < 0) {
35         perror("epoll_create");
36         return -1;
37     }
38
39     struct epoll_event events[10];
40     int pid = fork();
41     if (pid < 0) {
42         perror("fork");
43         return -1;
44     } else if (pid > 0) {
45         for (;;) {
46             int nfds = epoll_wait(epollfd, events, 10, -1);
47             if (nfds < 0) {
48                 perror("epoll_wait 1");
49                 return -1;
50             }
51             printf("wake up +++\n");
52         }
53     } else {
54         DoWrite(epollfd);
55     }
56     return 0;
57 }
                               
真实环境看起来很难犯这种错误,但其实在使用第三方库的时候,因为隐藏不少逻辑,犯错的概率就高了。比如在使用libevent的时候,fork出的子进程想要复用父进程的event_base是必需调用event_reinit的,但是不了解这个问题的人就会直接拿父进程的event_base来使用。看下event_reinit的代码,底层使用了epoll的重新epoll_create出一个epollfd的,而不是重用父进程的,也就是没有调用event_reinit,注册的读写事件,其实都是在父进程中那个epoll_wait那里返回。

epoll在fork子进程中的问题的更多相关文章

  1. epoll在socket通信中的应用

    当服务器需要服务多个客户时,需要使用并发通信,实现并发通信有以下几种方法: 1.在服务器中fork子进程来为每个客户服务  具体可参考http://www.cnblogs.com/ggjucheng/ ...

  2. epoll与fork

    使用epoll时,如果在调用epoll_create之后,调用了fork创建子进程,那么父子进程虽然有各自epoll实例的副本,但是在内核中,它们引用的是同一个实例.子进程向自己的epoll实例添加. ...

  3. fork子进程

    title: fork子进程 data: 2019/3/21 20:24:39 toc: true --- 这里实在学习socket编程前的小知识点,用来创建多个服务端 学习文档 函数可以有两个返回值 ...

  4. [fork]Linux中的fork函数详解

    ---------------------------------------------------------------------------------------------------- ...

  5. localtime死锁——多线程下fork子进程

    近期測试我们自己改进的redis,发如今做rdb时,子进程会一直hang住.gdb attach上.堆栈例如以下: (gdb) bt #0 0x0000003f6d4f805e in __lll_lo ...

  6. 缺陷的背后(四)---多进程之for循环下fork子进程引发bug

    导语 业务模块为实现高并发时的更快的处理速度,经常会采用多进程的方式去处理业务.多进程模式下常见的三种bug:for循环下fork子进程导致产生无数孙子进程,僵尸进程,接口窜包.本章主要介绍第一种常见 ...

  7. 转:fork()子进程创建

    源地址:http://blog.chinaunix.net/uid-23037385-id-2565472.html fork()子进程创建 在 UNIX 系统中,用户创建一个新进程的唯一方法就是调用 ...

  8. fork子进程僵尸问题及解决方案

    额,原来用 c 写 cgi 的时候用过 fork .那时候 cgi 的生命很短,所以遇到的问题压根没出现过.这次也是更加深入的对 fork 机制进行了一下了解. 参考这里的文档:http://ju.o ...

  9. fork子进程之间传输信息的方法(包含子进程与子进程之间区分的问题的解决)

    今天看到一道题,要求是父进程fork出两个子进程,子进程1需要给子进程2发送一个数据,然后子进程2再将这个数据发送给父进程 具体思想如下. 父进程fork出来的子进程的pid,只有父进程保存下来了, ...

随机推荐

  1. IntelliJ IDEA无法新建类解决办法

    IntelliJ IDEA无法新建类解决办法 灿夏 2018-07-14 08:50:05  4891  收藏 1 展开 原文地址 IntelliJ IDEA使用教程 (总目录篇) [原文地址](ht ...

  2. Eclipse中,No compiler is provided in this environment. Perhaps you are running on a JRE rather than a

    问题说明 Eclipse导入Maven项目后,执行 mvn clean install后,出现如下错误: [INFO] ---------------------------------------- ...

  3. ta-lib安装问题

    不管是windows还是linux,直接使用pip install ta-lib都会出现各种各样的问题,如下图: 解决办法,从网上找了很多办法都不好用,最后发现直接从晚上down .whl的文件,然后 ...

  4. 一个关于JVM类初始化问题

    刚在看虚拟机相关知识点 看到一段代码,大家猜测一下这段代码会触发子类初始化吗 public class SuperClass{ static{ system.out.println("Sup ...

  5. express框架路由未导出错误:Router.use() requires a middleware function but got a Object

    在路由的文件下加入导出语句 module.exports = router   导入与导出需要一一对应  

  6. 加薪攻略之UI组件库实践—storybook

    目录 加薪攻略之UI组件库实践-storybook 一.业务背景 二.选用方案 三.引入分析 项目结构 项目效果 四.实现步骤 1.添加依赖 2.添加npm执行脚本 3.添加配置文件 4.添加必要的w ...

  7. ES6 for of循环, 可迭代接口,实现可迭代接口

    在for of循环出现之前,for循环适合遍历普通的数组,for in循环比较适合遍历键值对,遍历数组对象的foreach方法,但是这些遍历 都有一定的局限性,所以在ES6之后引入了统一的遍历方式 f ...

  8. 关于Objects类的getClass方法为什么可以得到子类的地址的思考

    这一段时间,总是很纠结为什么Objects中的getClass方法可以返回包含子类地址信息的东西(我不确定返回值类型). 因为在Java中,我们定义的父类,我想破脑袋也想不出怎么可以得到子类的信息. ...

  9. MFC3 基本对话框的使用(三) 滑块与进度条(sdnu)(C++大作业)

    一.完成界面 运行前: 运行后: 二.工具 (1)滑块 (2)进度条 (3)文本框 (4)文本示例 (5)按钮 三.添加变量 四.添加事件 右键单击主对话框空白部分,打开类向导,选择"消息& ...

  10. WPF时间长度自定义选择控件TimeSpanBox

    以下控件采用https://www.cnblogs.com/cssmystyle/archive/2011/01/17/1937361.html部分代码 以下控件采用https://www.cnblo ...