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. flowable流程启动时监听器

    一.核心配置类 package com.magus.project.flow.config; import com.google.common.collect.Maps; import com.mag ...

  2. 【原创】Linux PCI驱动框架分析(二)

    背 景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本 ...

  3. Eclipse导入外部jar包的步骤

    (1)首先在项目的跟目录下先建一个名字为lib的文件夹,通常外部导入的jar包都放在这个文件夹下面. (2)将需要用到的jar包复制到lib文件夹下面. (3)在项目中导入jar包 右键项目,选择Bu ...

  4. 2.2.1 Sqoop1的基本架构

    当用户通过shell命令提交迁移作业后,Sqoop会从关系型数据库中读取元信息,并根据并发度和数据表大小将数据划分成若干分片,每片交给一个Map Task处理,这样多个Map Task同时读取数据库中 ...

  5. Logstash学习之路(三)Logstash处理时区、类型转换、删除字段的案例配置

    #输入 input { file { path => ["文件路径"] #自定义类型 type => "自定义" start_position =& ...

  6. <input type="image">表单提交2次 重复插入数据问题

    写一个表单提交用到图片:两种代码. <input type="image" src="xxx.gif"onclick="return dosub ...

  7. 在.NET Core中使用Channel(二)

    在我们之前的文章中,看了一些非常简单的例子来说明Channel是如何工作的,我们看到了一些非常漂亮的特性,但大多数情况下它与其他某某Queue实现非常相似.让我们进入一些更高级的话题.我说的是高级,但 ...

  8. 【JavaWeb】JSP 页面

    JSP 页面 简介 JSP(Java Server Pages),即 Java 的服务器页面.它的主要作用是代替 Servlet 程序回传 HTML 页面的数据,因为 Servlet 程序回传 HTM ...

  9. JavaFX之班级未交作业统计

    前言 最近转移了系统平台,用上了Ubuntu1804版本系统,原来用C#写的Windows窗体软件也不能用了,而且自己在班级上每周都需要收作业,所以写了这个软件.这篇博客主要记录这个JavaFX应用的 ...

  10. canvas多重阴影发光效果

    canvas多重阴影发光效果 前言 在一个项目中,客户提了一个发光的效果,效果图如下: 阴影 有的人可能会说,这个用阴影其实就可以实现.但是从图中可以看出,是一个比较强烈的发光效果.实际的应用过程中我 ...