日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux的进程与库之间的通信两种方式

發(fā)布時(shí)間:2023/12/10 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux的进程与库之间的通信两种方式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 前言
  • 一、進(jìn)程A與算法庫b的通信方式之一:動(dòng)態(tài)dlopen加載算法庫b,編譯的時(shí)候是需要加載該頭文件就可以,無需連接該算法庫b
    • 具體的實(shí)施細(xì)節(jié):
  • 二、進(jìn)程A與算法庫b的通信方式之二:進(jìn)程A編譯的時(shí)候連接上算法庫b和該頭文件
    • 具體的實(shí)施細(xì)節(jié):
  • 總結(jié)


前言

像平常主要是做視覺算法開發(fā)的,有時(shí)候算法效果實(shí)現(xiàn)了,但是要想要用產(chǎn)品上需要工程的實(shí)踐來串聯(lián)起算法和整個(gè)產(chǎn)品的連接關(guān)系。大部分AI的產(chǎn)品,算法一般實(shí)現(xiàn)之后,對(duì)外只會(huì)留兩個(gè)接口:1)輸入圖像、激光雷達(dá)、Imu等數(shù)據(jù);2)輸出算法的結(jié)果:機(jī)器人的狀態(tài)估計(jì)位置、速度、方向、圖像的檢測(cè)推理后篩選的坐標(biāo)等;但是這僅僅是視覺算法內(nèi)部的計(jì)算,產(chǎn)品它需要與其它模塊交互,像與控制器交互、與顯示的app交互;算法與外部模塊的交互就會(huì)涉及到,通信鏈路的工程化,你的數(shù)據(jù)要通過協(xié)議傳給接受方,所以涉及到自己的算法如何與自己通信進(jìn)程進(jìn)行交互問題,下面列些自己常用的兩種進(jìn)程與算法庫的通信交互方法,各有利弊。


一、進(jìn)程A與算法庫b的通信方式之一:動(dòng)態(tài)dlopen加載算法庫b,編譯的時(shí)候是需要加載該頭文件就可以,無需連接該算法庫b

具體的實(shí)施細(xì)節(jié):

1、構(gòu)建進(jìn)程A和算法庫b之前的一個(gè)公用頭文件,必須需要的三個(gè)函數(shù)以及兩個(gè)數(shù)據(jù)結(jié)構(gòu)、一個(gè)是進(jìn)程傳給算法庫的數(shù)據(jù)結(jié)構(gòu),一個(gè)是算法庫傳給進(jìn)程的數(shù)據(jù)結(jié)構(gòu)
2、定義三個(gè)函數(shù):初始化函數(shù)、進(jìn)程A回調(diào)算法庫b數(shù)據(jù)函數(shù)、算法庫b回調(diào)進(jìn)程A的數(shù)據(jù)函數(shù)
3、具體的頭文件.h和具體的.cpp實(shí)現(xiàn)
4.公共頭文件

公共頭文件,代碼如下:

//從進(jìn)程A中獲取,算法庫b開關(guān) typedef struct {//enableState 為0 不開啟算法庫b; 為1開啟算法庫bint enableState; }StateFromA;//發(fā)送給進(jìn)程A,算法庫b內(nèi)部運(yùn)行的狀態(tài) typedef struct {//sendState 1算法庫b開啟但未執(zhí)行(檢測(cè))、2算法庫b執(zhí)行中(檢測(cè))、3算法庫b執(zhí)行完成 4、算法庫b失敗int sendState; }StateToA;//typedef int (*b_flyCtrl_cb_func) (void* pData, int len); //typedef int (*b_PodCtrl_cb_func) (void* pData, int len); typedef int (*b_SendState_cb_func) (void* pData, int len); typedef int (*b_getbStateFromA_fn)(StateFromA* State); typedef int (*b_init_fn)(b_flyCtrl_cb_func cb_func1,b_PodCtrl_cb_func cb_func2,b_SendState_cb_func cb_func3);//進(jìn)程A調(diào)用算法庫b檢測(cè)算法庫的初始化函數(shù),并將算法庫b狀態(tài)和控制參數(shù)的回調(diào)函數(shù)的指針傳入算法庫中, extern "C" //進(jìn)程A可以同時(shí)實(shí)現(xiàn)三個(gè)回調(diào)函數(shù),將算法庫的內(nèi)部數(shù)據(jù)回調(diào)出去; 具體實(shí)現(xiàn)是在進(jìn)程A中實(shí)現(xiàn)該三個(gè)函數(shù),算法庫b只需要調(diào)用typedef新定義的三個(gè)回調(diào)函數(shù)的指針函數(shù)別名就可以,把相應(yīng)需要回調(diào)的函數(shù)結(jié)構(gòu)數(shù)據(jù)填寫進(jìn)去就可以實(shí)現(xiàn) //int b_init(b_flyCtrl_cb_func cb_func,b_PodCtrl_cb_func cb_func2,b_SendState_cb_func cb_func3); int b_init(b_SendState_cb_func cb_func3);//進(jìn)程A調(diào)用,算法庫b獲取進(jìn)程A是否開啟算法庫b的狀態(tài)信息 extern "C" int b_getbStateFromA(StateFromA* bState);

算法庫b的.cpp,代碼如下:

//從進(jìn)程A獲取算法b開關(guān)狀態(tài)信息,結(jié)構(gòu)體StateFromA* g_bStateInfoFromA = NULL;//進(jìn)程A從算法b獲取算法b內(nèi)部的運(yùn)行狀態(tài)信息,結(jié)構(gòu)體StateToA* g_bStateInfoFromb = NULL;g_bCtrl_cb ; //通過該控制1回調(diào)函數(shù)指針,將控制1的結(jié)構(gòu)體數(shù)據(jù)傳給進(jìn)程Ag_bCtrlPod_cb ;//通過該控制2回調(diào)函數(shù)指針,將控制2的結(jié)構(gòu)體數(shù)據(jù)傳給進(jìn)程AStateFromA g_ASendState_cb;//通過該進(jìn)程A回調(diào)函數(shù)指針,將算法庫b狀態(tài)的結(jié)構(gòu)體數(shù)據(jù)傳給進(jìn)程Aextern "C" //int b_init(b_flyCtrl_cb_func cb_func,b_PodCtrl_cb_func cb_func2,b_SendState_cb_func //cb_func3);//進(jìn)程A的回調(diào)函數(shù)入口,將回調(diào)函數(shù)指針通過初始化函數(shù)傳入到算法庫中 int b_init(b_SendState_cb_func cb_func3); {//g_bCtrl_cb = cb_func1; //通過該控制1回調(diào)函數(shù)指針,將控制1的結(jié)構(gòu)體數(shù)據(jù)傳給進(jìn)程A//g_bCtrlPod_cb = cb_func2;//通過該控制2回調(diào)函數(shù)指針,將控制2的結(jié)構(gòu)體數(shù)據(jù)傳給進(jìn)程Ag_bSendState_cb = cb_func3;//通過該進(jìn)程A回調(diào)函數(shù)指針,將算法庫b狀態(tài)的結(jié)構(gòu)體數(shù)據(jù)傳給進(jìn)程A//算法庫b,輸入數(shù)據(jù)結(jié)構(gòu)體申請(qǐng)內(nèi)存空間//給全局算法庫b的開啟狀態(tài)結(jié)構(gòu)體申請(qǐng)內(nèi)存空間,使用函數(shù)指針的別名來定義全局算法b是否能夠開啟狀態(tài)的結(jié)構(gòu)體b_SendState_cb_func g_ASendState_cb; return 0 }//相當(dāng)于算法庫b的輸入口,獲取了外部的狀態(tài) //算法庫b獲取進(jìn)程A中是否需要開啟算法b的狀態(tài),進(jìn)程A只需要將算法b需要的結(jié)構(gòu)體數(shù)據(jù)填寫進(jìn)去,算法b庫這邊的函數(shù)就會(huì)自動(dòng)的更新該算法b的開啟狀態(tài) extern "C" int b_getbStateFromA(StateFromA* bState); {if (StateToA== NULL)//所以進(jìn)程A先調(diào)用,算法庫b的初始化函數(shù),里面會(huì)給指針申請(qǐng)內(nèi)存{fprintf(stderr, "%s %d: ERROR! bStateFromb is NULL, return FAILURE.\n", __FUNCTION__, __LINE__);return -1;}else{//enableState: 為0 不開啟算法庫b; 為1開啟算法庫bg_bStateInfoFromA ->enableState = bState->enableState;return 0;} }int main() {//相當(dāng)于算法庫b的輸出口,發(fā)出去了了算法庫b自己的運(yùn)行狀態(tài) //發(fā)送算法b內(nèi)部運(yùn)行狀態(tài)給進(jìn)程A,通過A的回調(diào)函數(shù)接口(別名)去實(shí)現(xiàn)memset(g_bStateInfoFromb , 0, sizeof(StateToA));//發(fā)送算法b的內(nèi)部運(yùn)行狀態(tài)之前,先 結(jié)構(gòu)體數(shù)據(jù)都清零//調(diào)用進(jìn)程A的回調(diào)函數(shù)接口(回調(diào)函數(shù)別名),將算法庫b內(nèi)部的運(yùn)行狀態(tài)傳給進(jìn)程Ag_bSendState_cb((void *)g_bStateInfoFromb , (int)sizeof(StateToA)); }

進(jìn)程A的.cpp,代碼如下:

int ALibLoad(struct *ip) {//動(dòng)態(tài)裝載算法庫b動(dòng)態(tài)庫 void *bHandle = dlopen("/usr/lib/libb.so",RTLD_LAZY);if(bHandle ==NULL){printf("dlopen失敗:%s.",dlerror());return -1;}ip->bInitFuncPtr = (b_init_fn)dlsym(bHandle , "b_init");if( NULL == ip->bInitFuncPtr ){ pritnf("dlsym b_init 失敗:%s.",dlerror());return -1;}ip->bGetStateFuncPtr = (b_getbStateFromA_fn)dlsym(bHandle , "b_getbStateFromA");if( NULL == ip->bGetStateFuncPtr ){ printf("dlsym b_getbStateFromA失敗:%s.",dlerror());return -1;} } int AInit(struct *ip) {//進(jìn)程A回調(diào)算法庫b運(yùn)行狀態(tài)結(jié)構(gòu)體初始化memset(&ip->bGetStateFuncPtr, 0x00, sizeof(b_getbStateFromA));if (sem_init(&g_sembSendStateEvent, 0, 0)){binocularlog("g_sembSendStateEventinit failed, %d: %s", errno, strerror(errno));return -1;}//將算法庫b的初始化函數(shù)調(diào)用起來 //ip->bInitFuncPtr((b_flyCtrl_cb_func)bCtrlCbFun,(b_PodCtrl_cb_func)bPodCtrlCbFun,(b_SendState_cb_func)bStateCbFun); ip->bInitFuncPtr((b_SendState_cb_func)bStateCbFun); }//進(jìn)程A回調(diào)算法庫b的運(yùn)行狀態(tài)函數(shù)實(shí)現(xiàn) int bStateCbFun(void* pData, int len) {int rtn_cb = -1;StateToA*curbStateInfo = (StateToA*)pData;StateToA*tmpbStateInfo = new StateToA;memcpy(tmpbStateInfo , curbStateInfo , sizeof(StateToA));g_bSendStateDataQueue.push(tmpbStateInfo );sem_post(&g_sembSendStateEvent);rtn_cb = 0;return rtn_cb; }

二、進(jìn)程A與算法庫b的通信方式之二:進(jìn)程A編譯的時(shí)候連接上算法庫b和該頭文件

具體的實(shí)施細(xì)節(jié):

1、定義好進(jìn)程A和算法庫b使用的共同頭文件
2、該頭文件是以類的封裝形式展現(xiàn)出來,包括類的初始化函數(shù)、類的輸入數(shù)據(jù)接口、類的輸出數(shù)據(jù)接口
3、具體實(shí)現(xiàn)如下
公共頭文件,代碼如下:

//從進(jìn)程A中獲取,算法庫b開關(guān) typedef struct {//enableState 為0 不開啟算法庫b; 為1開啟算法庫bint enableState; }StateFromA;//發(fā)送給進(jìn)程A,算法庫b內(nèi)部運(yùn)行的狀態(tài) typedef struct {//sendState 1算法庫b開啟但未執(zhí)行(檢測(cè))、2算法庫b執(zhí)行中(檢測(cè))、3算法庫b執(zhí)行完成 4、算法庫b失敗int sendState; }StateToA;class B {B();~B(); public:int get (StateFromA bState);int output(StateToA &curbState); private: StateFromA m_bState; StateToA m_curbState;}

算法庫b的.cpp,代碼如下:

int B::get (StateFromA bState) {m_bState = bState;//外部數(shù)據(jù)傳給算法庫b的內(nèi)部私有變量m_curbState = 1;return 0; }int B::output(StateToA &curbState) {curbState = m_curbState;//將算法庫b運(yùn)行狀態(tài)傳輸給外部調(diào)用者return 0; }

進(jìn)程A的.cpp,代碼如下:

int main () {StateFromA g_bState;//定義進(jìn)程開啟算法庫b的結(jié)構(gòu)體數(shù)據(jù)變量g_bState = 0;//開啟算法庫bStateToA g_curbState;//定義進(jìn)程獲取算法庫b的運(yùn)行狀態(tài)結(jié)構(gòu)體數(shù)據(jù)變量B bobject;bobject.get (g_bState);//發(fā)送給算法庫b的開啟標(biāo)志位bobject.output(g_curbState);//獲取算法庫b內(nèi)部的運(yùn)行狀態(tài)return 0; }

總結(jié)

進(jìn)程與庫通信兩種方式的優(yōu)缺點(diǎn) 1、進(jìn)程與庫編譯相互依賴, 優(yōu)點(diǎn):庫里面可以自行使用類的函數(shù)來完成整理系統(tǒng)的處理 缺點(diǎn):庫的頭文件把整個(gè)類的處理函數(shù)都暴露給了進(jìn)程,外部可以看到庫的詳細(xì)信息、編譯需要依賴庫的存在 2、進(jìn)程編譯不依賴庫 優(yōu)點(diǎn):進(jìn)程編譯不依賴庫的存在、庫的內(nèi)部處理函數(shù)不會(huì)暴露給進(jìn)程 缺點(diǎn):進(jìn)程與庫需要操作加載庫,使用函數(shù)指針來調(diào)用庫的數(shù)據(jù),會(huì)形成很多單獨(dú)的通信接口 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的linux的进程与库之间的通信两种方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。