热替换so文件

www.zhaoch.top > 操作系统 > linux

发现nginx的动态模块无法热更新,于是研究了一下相关的问题。

代码准备

reload.c, 启动文件,用来模拟正在运行的程序,不断重建加载so.so文件

#include <dlfcn.h> #include <stdio.h>  typedef void (*F)();  int my_dlopen() {     void* h = dlopen("so.so", RTLD_NOW|RTLD_GLOBAL);     if (!h) {         fprintf(stderr, "%s\n", dlerror());         return 1;     }      F f = (F)dlsym(h, "action");     f();      return 0; }  int main(int argc, char const *argv[]) {     printf("start...\n");      while (1) {         printf("run\n");         if (my_dlopen() != 0) {             return 1;         }         sleep(2);     }      return 0; } 

so1.c 模拟其中一个so文件

#include <stdio.h>  void action() {     printf("11111111111111111\n"); } 

so2.c 模拟其中另一个so文件,接口相同,打印内容不同

#include <stdio.h>  void action() {     printf("222222222222222222222\n"); } 

编译

gcc reload.c -ldl -o reload gcc -fPIC -shared so1.c -o so1.so gcc -fPIC -shared so2.c -o so2.so 

注意

所有的实验需要 export LD_LIBRARY_PATH=./ 

第一次尝试,直接cp替换

先将 so1.so 设置成默认的 so文件

cp so1.so so.so 

启动程序, 然后执行 cp so2.so so.so

./reload  start... run 11111111111111111 run 11111111111111111 run 11111111111111111 run 11111111111111111  <-- 执行 cp so2.so so.so run [1]    38314 segmentation fault (core dumped)  ./reload 

程序直接崩溃

同时测试了下,rm so.so并不影响执行,但是停止程序再启动显示so.so: cannot open shared object file: No such file or directory 这个可能说明,so文件被打开一次后句柄并不会关闭,下次打开任然用这个句柄。只是重新读取文件。cp 改变文件内容,并不改变文件inode。

先rm再cp

cp so1.so so.so  ./reload start... run 11111111111111111 run 11111111111111111 run 11111111111111111 run 11111111111111111 run 11111111111111111  <-- rm so.so;cp so2.so so.so run 11111111111111111 run 11111111111111111 run 11111111111111111 

结果就是更新无效,猜想还是句柄没关闭的原因。rm的后,程序还指向原来的文件(这个文件外界看不到), cp产生了一个新的文件,程序根本没有理睬这个文件。

dlclose 再加载

在代码中加入 dlclose(h),如下:

int my_dlopen() {     void* h = dlopen("so.so", RTLD_NOW|RTLD_GLOBAL);     if (!h) {         fprintf(stderr, "%s\n", dlerror());         return 1;     }      F f = (F)dlsym(h, "action");     f();      dlclose(h); // <--      return 0; } 

这次可以了

./reload start... run 11111111111111111 run 11111111111111111 run 11111111111111111 run 11111111111111111   <-- cp so2.so so.so run 222222222222222222222 run 222222222222222222222 run 222222222222222222222 run 222222222222222222222 

说明确实时句柄的问题,这里涉及到linux inode的问题。每个文件都会对应一个inode, 内部都是按照inode来处理的,同一个文件名的不一定是同一个inode。一个文件只有在没有任何引用的时候才被删除,当程序打开一个so文件,这个文件就被引用了,即使外部删除这个文件,程序还是在使用这个so文件,这个文件只有在程序关闭时才被系统回收。cp过来时个全新的文件,只是文件名相同,inode并不相同,其实程序还是用着老的so文件。dlclose恰恰时关闭了这个文件,之后再次按文件名打开就是新的文件。

备注

看了下nginx的代码,貌似先dlopen之后再close旧的handle,这样是无法热更新的,不太清楚处于什么考虑。

The End

linux 热替换so文件的更多相关文章

  1. linux 批量替换所有文件中包含的字符串

    sed -i "s/原来字符串/新字符串/g" `grep 原来字符串 -rl .` 格式: sed -i "s/查找字段/替换字段/g" `grep 查找字段 ...

  2. linux批量替换指定文件夹中所有文件的指定内容

    命令:sed -i "s#https#http#g" `grep http -rl VEROMODA` 功能:用来替换当前目录VEROMODA文件夹及子文件夹中所有文件中的http ...

  3. Linux命令行批量替换多文件中的字符串【转】

    Linux命令行批量替换多文件中的字符串[转自百度文库] 一种是Mahuinan法,一种是Sumly法,一种是30T法分别如下: 一.Mahuinan法: 用sed命令可以批量替换多个文件中的字符串. ...

  4. Java_类的热替换

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/#ibm-pcon Java ClassLoader 技术剖析 在本文中,我们 ...

  5. Linux中环境变量文件及配置

    Linux中环境变量文件及配置   一.环境变量文件介绍 转自:http://blog.csdn.net/cscmaker/article/details/7261921 Linux中环境变量包括系统 ...

  6. 【转】class卸载、热替换和Tomcat的热部署的分析

    这篇文章主要是分析Tomcat中关于热部署和JSP更新替换的原理,在此之前先介绍class的热替换和class的卸载的原理.一 class的热替换ClassLoader中重要的方法 loadClass ...

  7. class卸载、热替换和Tomcat的热部署的分析

    一 class的热替换 ClassLoader中重要的方法 loadClassClassLoader.loadClass(...) 是ClassLoader的入口点.当一个类没有指明用什么加载器加载的 ...

  8. Java 类的热替换---转载

    构建基于 Java 的在线升级系统 Java ClassLoader 技术剖析 在本文中,我们将不对 Java ClassLoader 的细节进行过于详细的讲解,而是关注于和构建在线升级系统相关的基础 ...

  9. Linux中重命名文件

    linux下重命名文件有两种方式: 1.较简单的处理命令:mv mv 原文件名 新文件名 如:mv myFile newName 将MyFile重命名为newName. 2.linux提供了一个重命名 ...

随机推荐

  1. 数据库系统异常排查之DMV(转)

    来源: http://www.cnblogs.com/fygh/archive/2012/03/12.html 数据库系统异常是DBA经常要面临的情景,一名有一定从业经验的DBA,都会有自己一套故障排 ...

  2. SQL获取本周,上周,本月,上月的开始时间和结束时间

    ),),--本周 ),),--上周 ),),--本月 ),),--上月 ),),--近半年 ),)--近一年 ), ,, ),)--本周开始时间 ), ,, ),)--本周结束时间 ),,, ),)- ...

  3. 【Python自然语言处理】第一章学习笔记——搜索文本、计数统计和字符串链表

    这本书主要是基于Python和一个自然语言工具包(Natural Language Toolkit, NLTK)的开源库进行讲解 NLTK 介绍:NLTK是一个构建Python程序以处理人类语言数据的 ...

  4. WAKE-WIN10-SOFT-VS2013及工具

    1,下载安装,,,,,,, 2,配置 3opencv 3,1官网:http://opencv.org/ 3,3VS2013+OPENCV249配置 http://jingyan.baidu.com/a ...

  5. npm proxy设置网络代理 并使用taobao registry

    npm config set https-proxy http://server:portnpm config set proxy http://server:port npm set registr ...

  6. 从并发和索引说说innodb和myisam的区别

    一.引言 这个问题看似是个很俗气的问题,但是在面试中也是个经常被问到的问题.我想很多人都能说出几条,比如事物,外键,等等.但是我想这样想起一点说一句这么回答的话,知识其实都是分散的,这样就显得不是很高 ...

  7. Android坡度计

    艺术来源于生活,对我来说,编程也是一门艺术.今天发布这篇技术博客,就是我跟朋友在一次爬山过程中的争论,他跟我说那座山至少45度,我说没有,最多30度.我们彼此争论不休,于是我就想,为啥不写个手机程序来 ...

  8. pymongo 常用操作函数

    pymongo 是 mongodb 的 python Driver Editor. 记录下学习过程中感觉以后会常用多一些部分,以做参考. 1. 连接数据库 要使用pymongo最先应该做的事就是先连上 ...

  9. POJ-2976 Dropping tests---二分最大化平均值

    题目链接: https://cn.vjudge.net/problem/POJ-2976 题目大意: 给定n个二元组(a,b),扔掉k个二元组,使得剩下的a元素之和与b元素之和的比率最大 解题思路: ...

  10. Netbackup客户端安装网络放通端口需求,及测试网络放通方法

      192.168.1.101网络放通需求如下:   客户端主机 192.168.1.101 到 服务端主机 192.168.1.100 的1556.13720.13724.1378.13782这5个 ...