青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉,開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

Linux下C++ hot reload

Posted on 2011-07-01 17:03 S.l.e!ep.¢% 閱讀(1362) 評論(0)  編輯 收藏 引用 所屬分類: Unix

Linux下C++熱加載實例

Friday, 3. June 2011 - 16:21 |1 comment ?

假設一種環(huán)境,我們要對服務熱拔插一個動態(tài)庫(.so文件),所要考慮的是多線程環(huán)境的兼容,不會因為動態(tài)庫替換后造成棧損毀而崩潰
這邊想到的方法就是封裝一個dlopen過程作為對象實例加載(見load_so.h),當發(fā)出更新動態(tài)庫時重新dlopen過程,替換原先的實例,注意這個替換過程必須是溫和的、無逢的,這邊我們使用智能指針實現(xiàn)。

具體更新的實現(xiàn)通過一個單例(見do_sth.h),調用Reload重新加載動態(tài)庫。

我們構造一個極簡單的動態(tài)庫測試:
make_so.h

1
2
3
4
5
6
7
8
#include "say.h"
extern "C"
{
? ? void Enter(const std::string&str)
? ? {
? ? ? ? Say::instance().Sth(str); ? //在這里動態(tài)庫又過來調用了主程序的單件
? ? }
}

say.h 打印消息,這邊只是聲明一個單例,具體實現(xiàn)于主程序當中

1
2
3
4
5
6
#include "singleton.h"
class Say :public Singleton <Say>
{
? ? public:
? ? ? ? void Sth(const std::string&str);
};

通過編譯生test.so:
g++ make_so.cpp -fPIC -shared -pthread -rdynamic -lboost_thread -lboost_system -o test.so -L[boost庫目錄]

主程序 test.cpp ,用來測試這個動態(tài)庫test.so

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <boost/thread.hpp>
#include "load_so.h"
#include "say.h"

class DoSth :public Singleton
{
? ? public:
? ? ? ? DoSth():m_so(new LoadSo("./test.so"))
? ? ? ? {
? ? ? ? }

? ? ? ? DynamicSo_ptr Get()
? ? ? ? {
? ? ? ? ? ? boost::mutex::scoped_lock lock(m_mtx);
? ? ? ? ? ? return m_so;
? ? ? ? }

? ? ? ? void Reload()
? ? ? ? {
? ? ? ? ? ? boost::mutex::scoped_lock lock(m_mtx);
? ? ? ? ? ? m_so.reset(new LoadSo("./test.so"));
? ? ? ? }
? ? private:
? ? ? ? DynamicSo_ptr m_so;
? ? ? ? boost::mutex m_mtx;
};



/// Say
void Say::Sth(const std::string&str)
{
? ? std::cout<< str << std::endl;
}




////////////////////////// 測試代碼 //////////////////////////////////////

//更新動態(tài)庫
void test()
{
? ? for(int i=0;i<100;++i)
? ? {
? ? ? ? sleep(1);
? ? ? ? DoSth::instance().Reload();
? ? }
}

//運行動態(tài)庫
void test2()
{
? ? for(int i=0;irun("12");
? ? }
}

int main()
{
? ? std::cout<<"run\n";

? ? boost::thread thread1(&test2);
? ? boost::thread thread2(&test);

? ? thread1.join();
? ? thread2.join();

? ? return0;
}

編譯主程序:

g++ -Wall test2.cpp -o test2 -pipe -pthread -ldl -Wl,–export-dynamic -lboost_system -lboost_thread -L[boost庫目錄]

這邊一定要加“-Wl,–export-dynamic”以便導出主程序的符號供動態(tài)庫回調。

編譯成功后生成 test 可執(zhí)行文件,運行:

#./test
run
12
12
12
12
….

假設這時我們修改 make_so.h

1
2
3
4
5
6
7
8
#include "say.h"
extern "C"
{
? ? void Enter(const std::string&str)
? ? {
? ? ? ? Say::instance().Sth(str +",ab"); ? //修改輸出
? ? }
}

g++ make_so.cpp -fPIC -shared -pthread -rdynamic -lboost_thread -lboost_system -o test.so -L[boost庫目錄]
重新編譯后,這時我們主程序會馬上響應,輸出:

12,ab
12,ab
12,ab
12,ab
….

說明熱替換是成功的。

在實際運用中,當要替換動態(tài)庫時可以在程序中使用
DoSth::instance().Reload();
具體方法很多,可以通過socket、中斷信號、監(jiān)聽文件系統(tǒng)、定時更新等方式。

load_so.h 代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#ifndef LOAD_SO_H
#define LOAD_SO_H

#include
#include
#include
using namespace std;

class LoadSo
{
? ? typedefvoid(*Func)(const std::string&suid);
? ? public:
? ? ? ? LoadSo(constchar* so_file)
? ? ? ? {
? ? ? ? ? ? load(so_file);
? ? ? ? }

? ? ? ? ~LoadSo()
? ? ? ? {
? ? ? ? ? ? Close();
? ? ? ? }

? ? ? ? void Close()
? ? ? ? {
? ? ? ? ? ? dlclose(m_handle);
? ? ? ? }

? ? ? ? void run(const std::string&str )
? ? ? ? {
? ? ? ? ? ? m_func(str);
? ? ? ? }
? ? private:
? ? ? ? bool load(constchar* so_file)
? ? ? ? {
? ? ? ? ? ? m_handle = dlopen(so_file, RTLD_LAZY);
? ? ? ? ? ? if(!m_handle){
? ? ? ? ? ? ? ? std::string error("Cannot open library: ");
? ? ? ? ? ? ? ? throw std::runtime_error(error + dlerror());
? ? ? ? ? ? ? ? returnfalse;
? ? ? ? ? ? }

? ? ? ? ? ? dlerror();
? ? ? ? ? ? m_func =(Func) dlsym(m_handle, "Enter");
? ? ? ? ? ? constchar*dlsym_error = dlerror();
? ? ? ? ? ? if(dlsym_error){
? ? ? ? ? ? ? ? dlclose(m_handle);
? ? ? ? ? ? ? ? std::string error("Cannot load symbol: ");
? ? ? ? ? ? ? ? throw std::runtime_error(error + dlsym_error);
? ? ? ? ? ? ? ? returnfalse;
? ? ? ? ? ? }
? ? ? ? ? ? returntrue;
? ? ? ? }

? ? ? ? Func m_func;
? ? ? ? void* m_handle;
};
typedef boost::shared_ptr DynamicSo_ptr;

#endif

說在最后,我在一些測試中發(fā)現(xiàn)有時并不自動切換到新的動態(tài)庫的情況,另一個做法就是備用兩個動態(tài)庫,那么在Reload時在兩個so文件之間切換,這樣可以確保更新,額外給自己找的好處是可以保留舊版本的so。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲深夜福利在线| 欧美美女喷水视频| 美日韩免费视频| 欧美成人在线免费观看| 亚洲第一精品久久忘忧草社区| 久久久一本精品99久久精品66| 另类图片综合电影| 99re66热这里只有精品4| 日韩手机在线导航| 久久精品国产一区二区三| 美女国产精品| 国产一区二区视频在线观看| 亚洲精品视频在线播放| 久久久噜噜噜久久中文字免| 久久久久久久久久久成人| 国产精品乱码| 中文精品视频| 亚洲精品1区2区| 老色批av在线精品| 国产精品日韩精品| 亚洲综合色在线| 亚洲精品字幕| 欧美精品综合| 亚洲六月丁香色婷婷综合久久| 久久久国产精品亚洲一区 | 裸体一区二区| 欧美一区二区三区精品电影| 欧美资源在线| 久久精品九九| 亚洲激情第一区| 亚洲电影第1页| 欧美激情一区二区三区四区| 日韩视频在线观看免费| 亚洲精品男同| 国产精品视频久久久| 久久国产66| 麻豆成人综合网| 一本一道久久综合狠狠老精东影业 | 一区二区三区久久精品| 一本在线高清不卡dvd| 国产精品日韩在线一区| 久久嫩草精品久久久久| 亚洲精品一区二区网址| 亚洲高清视频在线| 国产精品视频xxx| 国产日韩欧美精品综合| 亚洲经典自拍| 欧美一区二区三区男人的天堂| 麻豆精品网站| 亚洲欧美激情在线视频| 欧美日本三级| 亚洲福利视频二区| 久久精品五月婷婷| 亚洲视频在线视频| 欧美日韩日日夜夜| 亚洲免费大片| 亚洲国内自拍| 久久精品五月| 韩日欧美一区| 久久久精品999| 欧美综合国产精品久久丁香| 国产欧美激情| 久久久久一区二区| 久久精品2019中文字幕| 樱花yy私人影院亚洲| 免费观看日韩av| 久久综合免费视频影院| 亚洲国产欧美一区二区三区丁香婷| 久久一区国产| 蜜桃精品久久久久久久免费影院| 亚洲第一网站| 91久久国产精品91久久性色| 欧美激情亚洲自拍| 亚洲婷婷在线| 亚洲一区三区视频在线观看| 国产亚洲成人一区| 麻豆精品视频在线观看视频| 蘑菇福利视频一区播放| 99热这里只有成人精品国产| 99精品欧美| 国产三区二区一区久久| 另类尿喷潮videofree| 欧美88av| 午夜精品久久久久久久| 久久福利影视| 日韩视频中午一区| 亚洲欧美美女| 亚洲国产精品悠悠久久琪琪| 日韩午夜av| 国内精品视频666| 亚洲精品在线一区二区| 国产在线欧美| 亚洲裸体在线观看| 国产一区久久| 夜夜嗨av一区二区三区免费区| 国产日韩视频| 亚洲美女电影在线| 狠狠色丁香婷综合久久| 亚洲免费观看高清在线观看| 先锋影音一区二区三区| 久久天堂成人| 亚洲一区二区三区四区五区午夜| 亚洲一区精品电影| 亚洲国产精品一区二区第一页| 99国产精品一区| 一区免费在线| 亚洲男人的天堂在线aⅴ视频| 亚洲人屁股眼子交8| 亚洲摸下面视频| 99re这里只有精品6| 久久婷婷国产综合尤物精品| 午夜精品婷婷| 欧美另类久久久品| 麻豆精品在线观看| 国产伦精品一区二区三| 亚洲日本电影在线| 亚洲国产日韩欧美在线99| 小嫩嫩精品导航| 亚洲欧美不卡| 欧美三区不卡| 亚洲看片网站| 亚洲裸体在线观看| 久热精品在线视频| 麻豆成人av| 国产一区二区三区视频在线观看| 亚洲免费播放| 一区二区三区久久久| 欧美高清视频免费观看| 欧美国产欧美亚洲国产日韩mv天天看完整 | 久久9热精品视频| 欧美色综合网| 日韩视频久久| 99成人在线| 欧美日韩不卡一区| 亚洲人成在线观看一区二区| 亚洲日韩中文字幕在线播放| 欧美成人久久| 亚洲精品久久久久久下一站| 亚洲精品乱码久久久久久日本蜜臀| 久久嫩草精品久久久精品一| 免费欧美高清视频| 亚洲国产一区二区视频| 欧美www在线| 亚洲美女av电影| 亚洲制服av| 国产精品久久久久久亚洲调教| 亚洲少妇自拍| 久久久www成人免费无遮挡大片| 国产亚洲女人久久久久毛片| 久久久久久9| 亚洲国产精品一区| 亚洲一区二区三区视频| 国产欧美一区二区三区久久 | 含羞草久久爱69一区| 欧美在线播放| 免费在线观看成人av| 亚洲清纯自拍| 欧美日韩精品欧美日韩精品一| 一区二区毛片| 久久精品国产一区二区三区免费看| 韩国欧美一区| 欧美精品97| 亚洲在线视频网站| 蜜臀av性久久久久蜜臀aⅴ四虎| 亚洲三级视频| 国产精品揄拍500视频| 另类天堂视频在线观看| 9l国产精品久久久久麻豆| 久久动漫亚洲| 99成人免费视频| 狠狠色2019综合网| 欧美日韩综合在线| 久久久久久一区二区| 在线性视频日韩欧美| 女同一区二区| 性色一区二区三区| 亚洲免费观看高清在线观看| 国产亚洲激情视频在线| 欧美巨乳波霸| 久久精品国产久精国产思思| 日韩一级片网址| 久久在线视频| 午夜视频在线观看一区二区三区| 亚洲国产欧美久久| 国产女人水真多18毛片18精品视频| 欧美freesex交免费视频| 亚洲欧美在线aaa| 日韩视频一区二区在线观看 | 欧美成人国产va精品日本一级| 亚洲砖区区免费| 亚洲黄色一区| 国内精品久久久久久久影视麻豆| 欧美日韩专区| 欧美国内亚洲| 蜜臀久久99精品久久久画质超高清 | 亚洲精品久久久久久久久久久| 久久综合色88| 玖玖视频精品| 久久福利电影| 久久99伊人|