此文主要記錄IPC項(xiàng)目中如何運(yùn)用循環(huán)隊(duì)列來(lái)處理多則消息的,網(wǎng)絡(luò)攝像頭下文簡(jiǎn)稱IPC。
在項(xiàng)目中,經(jīng)常會(huì)有網(wǎng)絡(luò)消息處理?,F(xiàn)在的安防攝像頭很多,通常也會(huì)配套一個(gè)APP去控制IPC,比如設(shè)置移動(dòng)檢測(cè)、人臉識(shí)別、嬰兒哭識(shí)別等等。在APP點(diǎn)擊一個(gè)button,可能會(huì)觸發(fā)APP通過(guò)網(wǎng)絡(luò)發(fā)送幾則消息給攝像頭。
這個(gè)時(shí)候,IPC需要處理這幾則或者十幾則消息。如果,IPC處理消息不是并發(fā)的,那么就需要不斷接收,不斷處理。這時(shí)候,運(yùn)用隊(duì)列的機(jī)制,可以讓先接收到的消息先處理。
而后接收的消息則等待,典型的先進(jìn)先出原則。如果IPC處理消息是并發(fā)的,同樣也可以運(yùn)用隊(duì)列的機(jī)制,只不過(guò)需要在每次訪問(wèn)隊(duì)列的時(shí)候加上鎖機(jī)制來(lái)同步資源。
IPC接收到的消息可能會(huì)包含APP用戶ID、請(qǐng)求的命令、消息的長(zhǎng)度等。
那如何處理這些消息呢?大致思路如下:
我們可以把每一則消息帶有的信息放到結(jié)構(gòu)體里面。這樣,每個(gè)結(jié)構(gòu)體就是隊(duì)列的一個(gè)成員。接收消息的線程把消息包裝成一個(gè)結(jié)構(gòu)體然后在隊(duì)列(數(shù)組)的尾部加上,處理消息的線程取出隊(duì)列的頭部來(lái)解析處理,每次解析處理完一則消息,就把消息從隊(duì)列的頭部移除。
所以,我們要定義一個(gè)結(jié)構(gòu)體數(shù)組,結(jié)構(gòu)體里面還能包含結(jié)構(gòu)體等,只要項(xiàng)目需要,都可以拓展。
程序模板比較簡(jiǎn)單,關(guān)鍵是知道怎么運(yùn)用到項(xiàng)目中。
其中需要注意的點(diǎn)是循環(huán)隊(duì)列如何判斷空還是滿。假設(shè)循環(huán)隊(duì)列長(zhǎng)度為5,當(dāng)頭指針和尾指針指向同一個(gè)地方,我們?cè)O(shè)為空。當(dāng)有元素入隊(duì),尾指針指向下一個(gè)元素,當(dāng)有元素出隊(duì),頭指針指向下一個(gè)元素。當(dāng)指向的元素為5時(shí),下一個(gè)元素為0。
這樣,得出的結(jié)論是,當(dāng)隊(duì)列為滿時(shí),頭指針和尾指針是相等的,這和隊(duì)列為空的時(shí)候是一樣的。不信,畫畫圖看看。
那怎么處理呢?
為了區(qū)別空隊(duì)列和滿隊(duì)列,數(shù)組多加一個(gè)元素,這個(gè)元素是不確定的,是可以移動(dòng)的,它將保證當(dāng)隊(duì)列為滿時(shí),還空留了一個(gè)位置。說(shuō)起來(lái)比較抽象,看以下代碼:
上面的函數(shù)是判斷隊(duì)列是否為滿。這樣和隊(duì)列是否為空的判斷方法不一樣:
所以,通過(guò)在循環(huán)數(shù)組中加多了一個(gè)元素,就能夠區(qū)分隊(duì)列是空的還是滿的。
大致的模板如下:
#include#include //構(gòu)造不完全填滿循環(huán)數(shù)組,以便區(qū)分隊(duì)列為空還是滿。 #define QUEUE_LEN 16 #define ARRAR_SIZE (QUEUE_LEN + 1) typedef struct student { int math; int English; char name[32]; } student; #define QUEUE_TYPE student typedef enum BOOL_ { false = 0, true = 1, }bool; //static使全局變量只在本文件中使用 static student studentTable[ARRAR_SIZE];//定義結(jié)構(gòu)體數(shù)組 static unsigned int front; //指向隊(duì)頭元素 static unsigned int tail; //指向隊(duì)尾元素的下一個(gè) bool IsQueueEmpty(void) { return (front == tail); } bool IsQueueFull() { return ((tail + 1) % ARRAR_SIZE == front); } bool queueInsert(QUEUE_TYPE value) { if(IsQueueFull()) return false; studentTable[tail] = value; tail = (tail + 1) % ARRAR_SIZE; return true; } bool queueDelete() { if(IsQueueEmpty()) return false; front = (front + 1) % ARRAR_SIZE; return true; } //測(cè)試程序 int main(int argc, char *argv[]) { student stu; stu.math = 99; stu.English = 98; char name[32]= "xiaoming"; memcpy(stu.name,name,sizeof(name)); queueInsert(stu); stu.math = 61; stu.English = 60; memset(name,0,sizeof(name)); sprintf(name,"xiaohong",sizeof(name)); memcpy(stu.name,name,sizeof(name)); queueInsert(stu); printf("front = %d,tail = %d,name = %s ",front,tail,studentTable[front].name); queueDelete(); printf("front = %d,tail = %d,name = %s ",front,tail,studentTable[front].name); return 0; }
測(cè)試結(jié)果如下:

審核編輯:湯梓紅
-
攝像頭
+關(guān)注
關(guān)注
61文章
4968瀏覽量
98101 -
網(wǎng)絡(luò)
+關(guān)注
關(guān)注
14文章
7802瀏覽量
90700 -
指針
+關(guān)注
關(guān)注
1文章
484瀏覽量
71125 -
IPC
+關(guān)注
關(guān)注
3文章
365瀏覽量
53059 -
隊(duì)列
+關(guān)注
關(guān)注
1文章
46瀏覽量
11068
原文標(biāo)題:循環(huán)隊(duì)列在網(wǎng)絡(luò)攝像頭項(xiàng)目中,處理多則消息的運(yùn)用
文章出處:【微信號(hào):c-stm32,微信公眾號(hào):STM32嵌入式開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
低功耗無(wú)線攝像頭項(xiàng)目合作
網(wǎng)絡(luò)攝像頭監(jiān)控的系統(tǒng)優(yōu)勢(shì)
基于labview的攝像頭幀錄像機(jī)
LabVIEW獲取網(wǎng)絡(luò)攝像頭方法
Labview隊(duì)列計(jì)時(shí)和隊(duì)列使用循環(huán)處理
【OK210申請(qǐng)】簡(jiǎn)易攝像頭監(jiān)控系統(tǒng)
【TL6748 DSP申請(qǐng)】指紋圖像處理項(xiàng)目、攝像頭視頻還原項(xiàng)目、音頻算法研究項(xiàng)目
labview調(diào)用網(wǎng)絡(luò)攝像頭時(shí)崩潰
隊(duì)列循環(huán)發(fā)送
開發(fā)一套基于人檢測(cè)AI的網(wǎng)絡(luò)攝像頭
IP網(wǎng)絡(luò)攝像頭解決方案

利用C++提供的隊(duì)列封裝一個(gè)消息隊(duì)列

如何使用ping命令測(cè)試網(wǎng)絡(luò)攝像頭連通性

評(píng)論