linux 热替换so文件
热替换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
- My github location
- View Source of this website GhostZch.github.io
- Commit issues to discuss with me and others
linux 热替换so文件的更多相关文章
- linux 批量替换所有文件中包含的字符串
sed -i "s/原来字符串/新字符串/g" `grep 原来字符串 -rl .` 格式: sed -i "s/查找字段/替换字段/g" `grep 查找字段 ...
- linux批量替换指定文件夹中所有文件的指定内容
命令:sed -i "s#https#http#g" `grep http -rl VEROMODA` 功能:用来替换当前目录VEROMODA文件夹及子文件夹中所有文件中的http ...
- Linux命令行批量替换多文件中的字符串【转】
Linux命令行批量替换多文件中的字符串[转自百度文库] 一种是Mahuinan法,一种是Sumly法,一种是30T法分别如下: 一.Mahuinan法: 用sed命令可以批量替换多个文件中的字符串. ...
- Java_类的热替换
转自:http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/#ibm-pcon Java ClassLoader 技术剖析 在本文中,我们 ...
- Linux中环境变量文件及配置
Linux中环境变量文件及配置 一.环境变量文件介绍 转自:http://blog.csdn.net/cscmaker/article/details/7261921 Linux中环境变量包括系统 ...
- 【转】class卸载、热替换和Tomcat的热部署的分析
这篇文章主要是分析Tomcat中关于热部署和JSP更新替换的原理,在此之前先介绍class的热替换和class的卸载的原理.一 class的热替换ClassLoader中重要的方法 loadClass ...
- class卸载、热替换和Tomcat的热部署的分析
一 class的热替换 ClassLoader中重要的方法 loadClassClassLoader.loadClass(...) 是ClassLoader的入口点.当一个类没有指明用什么加载器加载的 ...
- Java 类的热替换---转载
构建基于 Java 的在线升级系统 Java ClassLoader 技术剖析 在本文中,我们将不对 Java ClassLoader 的细节进行过于详细的讲解,而是关注于和构建在线升级系统相关的基础 ...
- Linux中重命名文件
linux下重命名文件有两种方式: 1.较简单的处理命令:mv mv 原文件名 新文件名 如:mv myFile newName 将MyFile重命名为newName. 2.linux提供了一个重命名 ...
随机推荐
- 別人寫的git的總結,寫自己這裡學習用
這裡是原文,http://www.cnblogs.com/ang-/p/7352909.html 貼這裡慢慢學. git入门大全 阅读目录 前言 基本概念 文件几种状态 创建新仓库 配置 检出仓库 ...
- mongodb 3.4 学习 (二)命令
# 使用或切换数据库 use <database name> # 显示所有数据库 show dbs # 显示所有collection show collections # 显示所有user ...
- Nginx+Tomcat在Windows下做负载均衡
一. 为什么需要对Tomcat服务器做负载均衡 Tomcat服务器作为一个Web服务器,其并发数在300-500之间,如果有超过500的并发数便会出现Tomcat不能响应新的请求的情况,严重影响网站的 ...
- Python3循环语句
Python3 循环语句 Python中的循环语句有for和while. 循环语句控制结构图如下: 一.while循环 ①循环结构 while 判断条件: 执行语句 实例: n = int(input ...
- 安卓Socket开发注意事项
如果要在安卓app里用到Socket通信,要满足: 1.在写代码的activity里import进Socket相关的包,这个很easy,如果你不知道要import什么包,也可以先不指定,可 ...
- Zookeep启动异常:Error contacting service. It is probably not running.
异常提示: [root@hadoop bin]# ./zkServer.sh status JMX enabled by default Using config: /usr/local/zk/bin ...
- 用js写三级联动
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- "应用程序无法正常启动(0xc000007b)。请单击 确定 关闭应用程序。"解决方法
完成一小项目,正常运行,测试环境有Windows XP,Win 7,Win X64及有SP的版本,也是我客户端可能用到的系统版本,Win8和Win10未测试 但在分发过程中,发现有的机器可以正常运行, ...
- 【luogu P3376 网络最大流】 模板
题目链接:https://www.luogu.org/problemnew/show/P3376 #include <iostream> #include <cstdio> # ...
- 优雅的QSignleton (五) 优雅地进行GameObject命名
这段时间空调吹感冒了,休息了好久 本篇介绍QSingleton最重要的功能,是它让QSingleton称得上优雅.相关内容之前介绍过. 代码如下: MonoSingletonPath.cs n ...