热替换so文件

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

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

代码准备

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

#include #include 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 void action() { printf("11111111111111111\n"); }

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

#include 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

程序直接崩溃

同时测试了下,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的后,程序还指向原来的文件(这个文件外界看不到), 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); //

这次可以了

./reload start... run 11111111111111111 run 11111111111111111 run 11111111111111111 run 11111111111111111

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

备注

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

The EndMy github location

View Source of this website GhostZch.github.io

Commit issues to discuss with me and others

linux so替换,linux 热替换so文件相关推荐

  1. vue+webpack热替换

    项目地址:http://pan.baidu.com/s/1i5KCXBf 今天上午和同事完成了在mac上面调试了我的框架,最后发现问题出在window系统和mac系统在表示路径的时候出现问题,在解决这 ...

  2. webpack学习(七):启用 HMR(模块热替换)

    demo地址: https://github.com/Lkkkkkkg/webpack-demo 上次使用 webpack-dev-serve : https://blog.csdn.net/qq59 ...

  3. linux 文件 图标 覆盖,在Deepin下处理Microsoft Edge替换图标及替换文件

    Microsoft推出的Edge for Linux版本可正常使用在Deepin系统下,本文介绍其替换图标及替换文件的方法.如果要安装,可去下载,并在终端中执行sudo dpkg -i  micros ...

  4. linux替换jar包目录,Linux下用jar命令替换war包中的文件【转】

    问题背景:在Linux环境上的weblogic发布war包,有时候只是修改了几个文件,也要上传整个war包,这样很费时间,因此整理了一下Linux环境,更新单个文件的方法. 1.如果要替换的文件直接在 ...

  5. linux 文件 查找内容替换,linux递归查找文件内容并替换

    sed -i 's/原字符串/替换后字符串/g' `grep '搜索关键字' -rl /data/目标目录/ --include "*.html"` 上面是递归查找目录中所有的HT ...

  6. linux替换jar的文件,Linux下用jar命令替换war包中的文件【转】

    问题背景:在Linux环境上的weblogic发布war包,有时候只是修改了几个文件,也要上传整个war包,这样很费时间,因此整理了一下Linux环境,更新单个文件的方法. 1.如果要替换的文件直接在 ...

  7. linux sed 选取,linux sed 替换(整行替换,部分替换)、删除delete、新增add、选取...

    sed命令行格式为: sed [-nefri] 'command' 输入文本 常用选项: -n∶使用安静(silent)模式.在一般 sed 的用法中,所有来自 STDIN的资料一般都会被列出到萤幕上 ...

  8. dd实现Linux转移,linux命令-dd {拷贝并替换}

    一 命令解释: dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: if=文 ...

  9. 【Linux】进程的程序替换

    文章目录 1. 程序替换 1.创建子进程的目的是什么? 2.了解程序是如何进行替换的 3. 程序替换的基本原理 当创建进程的时候,先有进程数据结构,还是先加载代码和数据? 程序替换是整体替换,不是局部 ...

  10. linux中替换命令详解,linux中sed命令字符串替换的用法详解

    Linux系统中sed命令可以将字符串批量替换,省去了很多麻烦,下面由学习啦小编为大家整理了linux系统中sed命令字符串替换的用法详解,希望对大家有帮助! linux中sed命令字符串替换的用法详 ...

最新文章

  1. 电商系统的高并发设计和挑战
  2. 【arduino】用VSCode替代Arduino编辑器,arduino VSCode编辑器
  3. AI:2020年6月22日北京智源大会演讲分享之09:00-09:50 全体大会《AI精度与隐私的博弈》
  4. Winform中实现将照片剪贴到系统剪切板中(附代码下载)
  5. CSS基础(part19)--CSS3属性选择器
  6. python利用特征进行可视化样本显示_利用Python进行机器学习之特征选择
  7. ubuntu11.10 源码编译安装php5.3.8,Ubuntu 11.10编译安装Nginx、PHP 5.3.8、MySQL、MongoDB、Memcached、SSL、SMTP...
  8. Docker for windows 容器内网通过独立IP直接访问的方法
  9. php openssl des ecb,php7.2 des-ede3-ecb加密报错:openssl_encrypt():Unknown cipher algorithm 落叶随风博客...
  10. 官网下载mysql连接驱动jar包教程
  11. 自然语言处理--基于规则(AIML)的问答机器人
  12. 1s看懂555定时器,以及应用?
  13. MF前传——探索者一号液晶屏接线
  14. win10企业版2016长期服务激活教程
  15. c语言入门编辑什么,萌新必看——C语言入门编辑器推荐
  16. 从“网红”到“超级网红”,长沙凭什么这么火?
  17. Python的整数与浮点数计算
  18. GD32F407移植SR8201F
  19. 1060显卡用什么软件测试,科技 篇七:有了它,GTX1060竟变智商检测卡!
  20. FreeSwitch调试小技巧

热门文章

  1. linux下飞信安装详细过程
  2. 解决在IE浏览器中JQuery.resize()执行多次的方法(转)
  3. 计算机包括桌面计算机和便携式计算机,【填空题】( )计算机包括桌面计算机和便携式计算机这两种形式。...
  4. agax分页查询必知知识,分页必须参数详解
  5. mamp 扩展 php,Mac OS 下如何在 MAMP Pro 中安装php 扩展 zip
  6. 眼图在通信系统中有什么意义_KT124煤矿调度通信系统和传统调度系统相比有什么优势...
  7. cnn程序流程图_GitHub - suqcnn/vue: vue源码逐行注释分析+40多m的vue源码程序流程图思维导图 (diff部分待后续更新)...
  8. WPF中的相关属性含义
  9. C# 从MongoDB导入数据到mysql
  10. 我要做 Android 第三弹弹弹