zoukankan      html  css  js  c++  java
  • 多线程同时操作一个epoll_fd

    为什么选择多线程?而不是多进程?

    比起多进程来说,线程间通信简单(全局变量就可以了),而多进程之间的通信相对而言更繁琐一些,呵呵...

    我们的问题如何产生的?问题的根本原因是什么?

    事情是这样的,模块之间需要通信,我们用了openwrt的开源代码ubus做消息转发

    在我们的每个需要通信的模块中创建了一个线程(ubus thread)循环接收ubusd转发而来的消息(用的是libubox提供的API  uloop_run)

    在模块需要发送时,主线程调用ubus的消息发送接口(ubus_send_event)

    大多数情况是这样的:

    1. 模块(作为一个后台进程)启动时装载了libubox.so(注意,这个库的载入时加入了一个全局变量 int epoll_fd)

    2. 随即就创建线程ubus thread循环等待接收消息,ubus thread的动作大致如下:

        a. 建立和ubusd通信的socket(记为fd1)

        b. 随即调用epoll_ctl将fd1加入到epoll_fd中

        c. 然后调用epoll_wait....

    3. 主线程执行,在有需要的时候,调用ubus_send_event发送

        实际上这个库接口做的动作是这样的:

        a. 建立和ubusd通信的socket(记为fd2)

        b. 将fd2加入到全局变量epoll_fd,然后执行epoll_wait(epoll_fd没有创建的话,先调用epoll_create)

    那么问题来了,一般都是ubus thread先执行,然后阻塞在epoll_wait中,主线程在ubus thread阻塞时将fd2加入到同一个epoll_fd中....

    也就是两线程在操作同一个epoll_fd

    结果fd2状态发生变化时,ubus thread被唤醒执行了,然后就乱套了......

    尝试了一下,在主线程发送的时候去fork子进程,子进程完成发送的动作,反而更悲剧了,整个进程崩掉了....

    为啥呢,因为fork出来的子进程没有执行exec切换进程执行上下文,完全是一个父进程的拷贝,那个出问题的epoll_fd也被它拿着了

    然后子进程新建了一个和ubusd通信的fd2,加入到这个epoll_fd中,然后执行epoll_wait

    结果fd2发生状态变化时,内核唤醒了ubus thread,尼玛,ubus thread哪里知道fd2的存在,结果非法地址访问,Segmentfault....呵呵...


    最后,最后,因为我们这群小蜜蜂实在是飞得太低,所以,我们借助了ubus源码附带提供的ubus命令行工具

    在主线程发送时 system("ubus send %s ", message)

    这就相当于在主线程发送时fork子进程,然后子进程的执行环境切换到ubus工具,ubus工具会调用ubus_send_event

    另一种解决方案:

    还是在主线程发送的时候去fork子进程,子进程一上来直接去循环关闭从0-1024的fd,哈哈哈哈...(不知道会不会有什么其他的影响,不过我觉得应该可以)

    for (i = 0; i < FDSET; i++)

      close(i)

    这样做是强迫子进程再次去调用epoll_create,而不是复用从父进程那里继承而来的epoll_fd。

    所以,用了开源库,加上我们独特的线程设计,给自己整了个大坑....

  • 相关阅读:
    python中的字符数字之间的转换函数
    java中的this和super的作用和异同和C++中调用父类的构造函数
    夺命雷公狗---Smarty NO:19 html_options函数
    夺命雷公狗---Smarty NO:18 html_checkboxes
    夺命雷公狗---Smarty NO:17 html_table函数
    夺命雷公狗---Smarty NO:16 html_image函数
    夺命雷公狗---Smarty NO:15 fetch函数
    夺命雷公狗---Smarty NO:14 debug调试
    夺命雷公狗---Smarty NO:13 系统自定义函数(plugins)
    夺命雷公狗---Smarty NO:12 section函数
  • 原文地址:https://www.cnblogs.com/xiaokuang/p/4793312.html
Copyright © 2011-2022 走看看