C++中的類加多線程代碼修煉

背景:現在在做一個目標跟蹤的項目,需要實時的從工業相機中獲取圖像,然后再跟蹤圖像上的目標物,由于起初為了測試跟蹤算法,就把“從相機獲取圖像”和“跟蹤處理”都放在了主線程中,在實際測試時,直接從相機獲取圖像時,跟蹤處理部分幀率出現周期性卡頓的問題,而直接讀取本地的視頻數據時跟蹤部分幀率很穩。因為“獲取圖像”和“跟蹤處理”在一個線程中,所以兩者是一條線上的螞蚱,要快都快,要慢都滿,所以我沒必要在幀率測試上花時間了,另外考慮到,相機應該單獨出來,一個是將一些相機的操作封裝到一個類里面,另外需要將他放在一個線程中去,這樣這個線程只顧獲取圖像就可以不受其他操作的影響。又考慮到以后還會有數據處理這一塊,所以把跟蹤這塊也封裝到一個類中,也放在一個單獨的線程中去。

說自己是C++程序猿真是慚愧,使用C++也快5年了,期間也專門拿兩個月專門來學習C++語法,但是一直以來練習的太少,導致現在的水平依然很低,今天問我老同事相關問題,他直接給我發了一個“頭上頂著菜葉子的狗”,名副其實呀,我感覺我就是個菜狗,哈哈,我要盡早擺脫這個稱號。

雖然我的C++功底不深厚,但是還是有一些基礎和經驗的,我知道第一步需要做的就是把架子搭建起來,然后通過了,然后再往里面填東西。

獲取圖像的類 CaptureThread.h

#ifndef CAPTURETHREAD_H
#define CAPTURETHREAD_H
namespace FDSST {
class CaptureThread {
public:CaptureThread();~CaptureThread();void Run();void Stream();void Pause();void Stop();bool quit;
private:bool pause_status;
};
}
#endif // CAPTURETHREAD_H

獲取圖像類實現:CaptureThread.cpp

#include <iostream>
#include "../include/capturethread.h"
#include <windows.h>namespace FDSST
{
CaptureThread::CaptureThread()
{pause_status = false;quit = false;
}
CaptureThread::~CaptureThread()
{
}
void CaptureThread::Run()
{std::cout << "capture_thread!!!" << std::endl;return;
}
void CaptureThread::Stream()
{pause_status = false;
}void CaptureThread::Pause()
{pause_status = true;
}void CaptureThread::Stop()
{pause_status = true;quit = true;
}
}

跟蹤類:TrackingThread.h

#ifndef TRACKINGTHREAD_H
#define TRACKINGTHREAD_Hnamespace FDSST
{
class Tracking {
public:Tracking();~Tracking();void Run();
};
}
#endif

跟蹤類實現:TrackingThread.cpp

#include <iostream>
#include "../include/trackingthread.h"
#include <windows.h>
namespace FDSST
{Tracking::Tracking(){}Tracking::~Tracking(){}void Tracking::Run(){std::cout << "tracking_thread!!!" << std::endl;return;}
}

我學著orb-slam代碼結構的樣子,整出來一個System類:System.h

#ifndef SYSTEM_H
#define SYSTEM_H
#include <thread>
#include "../include/Trackingthread.h"
#include "../include/capturethread.h"
namespace FDSST
{
class Tracking;
class CaptureThread;class System {
public:System();~System();
private:Tracking* mpTracker;CaptureThread* mpCapturer;std::thread* mptTracking;std::thread* mptCapturing;
};
}
#endif

Syetem.cpp

在System類的構造函數中,創建兩個線程,將CaptureThread類和Tracking類中的成員函數Run作為線程的入口

#include "../include/System.h"
#include <thread>namespace FDSST {System::System(){mpCapturer = new CaptureThread();mptCapturing = new std::thread(&FDSST::CaptureThread::Run, mpCapturer);std::cout << "Capture thread has been created" << std::endl;mpTracker = new Tracking();mptTracking = new std::thread(&FDSST::Tracking::Run, mpTracker);std::cout << "Tracking thread has been created" << std::endl;}System::~System(){}
}

我們想象的多線程的樣子都是,代碼執行起來之后,兩個線程中代碼段一直在執行,直到到達代碼控制它結束的時候。看我在主函數中是怎么調用System的構造函數,從而創建兩個線程的。

我最初的寫法是這樣的:

#include <iostream>
#include "../include/System.h"
#include <windows.h>int main(int argc, char** argv)
{FDSST::System TRACK();return 0;
}

此時代碼可以編譯通過,但是我發現程序并沒有進入到System類中的構造函數中去,所以線程被創建的打印未輸出。我很納悶,為啥那塊代碼沒有被執行呢?

我就去請教我的老同事,一個很低調很牛的boy,我把主函數和System.cpp的內容截圖發給他,他一看就知道了,他讓我把FDSST::System TRACK();中的括號去掉,原因是,我在System.cpp中的默認構造函數中執行創建線程的操作,而如果我的TRACK后面帶有括號,就不會調用默認構造函數,我這種寫法在某些編譯器上應該會出錯的。

也就是說,
?? ?如果我使用的是默認的構造函數那么就得這樣定義 :FDSST::System TRACK;
?? ?如果我定義了帶參數的構造函數,那就可以定義為:FDSST::System TRACK(paras);

上面的問題解決之后,CaptureThread和TrackingThread類中Run函數中的打操作只被執行了一次,我就又納悶了,咋跟我想象的不一樣,應該一直執行下去,我繼續問我那個老同事事,他說需要加上while(1),我知道了是在Run函數里面加while(1).上面的Run函數改成下面這種寫法。

void CaptureThread::Run()
{while (1){std::cout << "capture_thread!!!" << std::endl;}return;
}
void Tracking::Run()
{while (1){std::cout << "tracking_thread!!!" << std::endl;}return;
}

然后我發現Run函數中的打印操作還是只執行了一次,我又納悶了,又問我那老同事,他說,"你的主函數結束了吧”,讓我在main函數中添加Sleep()函數。我把主函數改成下面這個樣子

#include <iostream>
#include "../include/System.h"
#include <windows.h>int main(int argc, char** argv)
{FDSST::System TRACK();Sleep(10000);return 0;
}

修改之后,代碼可以一直執行了,但是我發現,兩個線程的輸出呈現交替執行的現象,一個線程執行很多次,然后另外一個線程再執行很多次,交替執行,像下面這樣。

?我又問我老同事,他讓我在每一個Run函數中也加上Sleep(),我就把Run函數中加上Sleep()

void CaptureThread::Run()
{while (1){std::cout << "capture_thread!!!" << std::endl;Sleep(2);}return;
}
void Tracking::Run()
{while (1){std::cout << "tracking_thread!!!" << std::endl;Sleep(2);}return;
}

這下再執行:就正常了,接下來就可以往里面實現功能了。雖然這個框架很簡單,但是在搭建出來的過程中讓我學到很多東西,所以將難得問題拆分成簡單的問題,一步一步的來,就可以解決。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/252307.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/252307.shtml
英文地址,請注明出處:http://en.pswp.cn/news/252307.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Activity Monitor 閃退 無法進入睡眠

Activity Monitor 閃退 & 無法進入睡眠 情況描述 黑蘋果?主機突然無法進入睡眠。 考慮到可能是后臺程序阻礙了系統正常進入睡眠&#xff0c; 于是想要通過Activity Monitor查看系統的活動情況&#xff0c;然而&#xff0c;Activity Monitor閃退。 重新開機&#xff0c;快速…

hbase中清空整張表的數據

hbase(main):005:0> truncate fr:test Truncating FaceBase table (it may take a while):- Disabling table...- Dropping table...- Creating table...0 row(s) in 14.4220 seconds truncate是disable、drop、create三個動作的自動化集成。轉載于:https://www.cnblogs.com…

hibernate樹

1. 樹實現通過pid進行指向上一層來實現&#xff0c;實體類代碼如下 package com.test.model;import java.util.HashSet; import java.util.Set;import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.per…

Sleep() sleep() usleep()

Linux: sleep(n); //停留n秒 usleep(n); //停留n微秒 Windows: Sleep(n); //停留n毫秒

vue的鼠標移入和移出

vue的鼠標移入和移出 需求&#xff08;鼠標到預約二維碼顯示&#xff0c;預約添加背景色&#xff09; 實現 <!--html部分--> <ul class"person_list"> //五個li標簽皆是循環渲染出來的<li class"item" v-for"(n,index) in 5">…

聊聊flink的MemoryPool

為什么80%的碼農都做不了架構師&#xff1f;>>> 序 本文主要研究一下flink的MemoryPool MemoryPool flink-runtime_2.11-1.7.2-sources.jar!/org/apache/flink/runtime/memory/MemoryManager.java abstract static class MemoryPool {abstract int getNumberOfAvai…

day4

ti很簡單&#xff0c;但是把變量弄錯了&#xff0c;寫了不到半小時&#xff0c;調了一小時&#xff0c;導致t3功虧一簣。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> …

C++中public protected private的區別

1. 不考慮繼承關系時 本類方法使用外部使用private是否protected是否public是是 2. 有繼承關系時 子類方法使用外部private否否protected是否public是是 結論&#xff1a;基于以上兩個表格可以知道&#xff0c;C中的protected處于private和public中間&#xff0c; protected 既…

表達式求值

表達式求值問題 ①問題描述 表達式是數據運算的基本形式。人們的書寫習慣是中綴式&#xff0c;如&#xff1a;1122*(7-4)/3。中綴式的計算按運算符的優先級及括號優先的原則&#xff0c;相同級別從左到右進行計算。表達式還有后綴式&#xff08;如&#xff1a;22 7 4 - * 3 / 1…

PHP_SELF變量解析和重復路徑解決

最近升級PHP到PHP7版本&#xff0c;并重新部署了新的Nginx&#xff0c;啟動的時候發現了一個問題&#xff0c;全局變量$_SERVER[PHP_SELF]的值發生了改變&#xff0c;從而影響到代碼的功能。因此我們來了解下$_SERVER全局變量中的PHP_SELF/PATH_INFO/SCRIPT_NAME等參數以及其關…

pep 8 規范的一些記錄

一、pep8起源 龜叔創立Python的初衷里就有創立一個容易閱讀的編程語言&#xff0c;所以親自操刀寫了pep8 代碼規范&#xff0c;每個項目開始前都要有一個共識&#xff0c;就是自己的代碼規范&#xff0c;pep8 就是一個很好的范本。 二、官網鏈接 https://www.python.org/dev/pe…

C++中的類加多線程代碼修煉之二

背景&#xff1a;在上一篇文章中 寫到了我第一次使用C使用多個類多個線程進行編程&#xff0c;由于是第一接手“這么大一個工程”&#xff0c;所以還是要有個參照物的&#xff0c;由于我呢之前好幾年一直在看的一個C代碼工程就是ORB-SLAM了&#xff0c;這個工程使用C語言&#…

Primer c++ 第5版pdf

下載地址&#xff1a;網盤下載 內容簡介 這本久負盛名的 C經典教程&#xff0c;時隔八年之久&#xff0c;終迎來史無前例的重大升級。除令全球無數程序員從中受益&#xff0c;甚至為之迷醉的——C 大師 Stanley B. Lippman 的豐富實踐經驗&#xff0c;C標準委員會原負責…

eclispe修改project Explorer字體大小

切換到Eclipse目錄下: D:\JAVA\spring-tool-suite\sts-4.0.2.RELEASE\plugins\org.eclipse.ui.themes_1.2.200.v20180828-1350 找到下面的這個css文件 打開找到下面的位置在下面添加代碼:CTabFolder Tree{font-size: 15px;} 復制代碼重啟Eclipse,就可以看到效果 修改前 修改后…

3-4 第三天 Generator生成器

Generator是ES6里面的新增規范&#xff0c;ES6其實就是ES2015。ES5、ES6、ES7這些術語大家上網一查就都明白了。JavaScript是一個范程&#xff0c;就是我們說的JS。ES就是ECMA Script&#xff0c;是JavaScript標準的書面說法。ES4、5、6、7其實是JS這門語言發展中的不同的版本。…

神奇的事情--長見識了

背景&#xff1a;我的這個工程里有多個命名空間&#xff0c;之所以是這樣是因為&#xff0c;有一個跟蹤算法他本身有幾個namespace,然后我在他的基礎上進行整合代碼&#xff0c;將其作為一個功能接口&#xff0c;供其他函數調用&#xff0c;我在整合代碼時&#xff0c;將我新加…

箭頭函數的使用用法(一)

1 //箭頭函數的一個好處是簡化回調函數2 //箭頭函數沒有參數&#xff0c;就使用圓刮號代表參數部分&#xff1b;3 var f () >5;4 console.log(f());5 //兩個參數的情況&#xff0c;代碼塊只有一條語句&#xff0c;可以省略{}6 var f (a,b)> console.log(ab);7 f(1,3);8…

LinkedList中查詢(contains)和刪除(remove)源碼分析

一、contains源碼分析 本文分析雙向鏈表LinkedList的查詢操作源碼實現。jdk中源程序中&#xff0c;LinkedList的查詢操作&#xff0c;通過contains(Object o)函數實現。具體見下面兩部分程序&#xff1a;① public boolean contains(Object o) {return indexOf(o) ! -1; } ② p…

分塊入門

我貌似和所有的數據結構都有些誤會。。。。。。 在處理一些修改查詢問題的時候&#xff0c;我們可以利用分治的思想&#xff0c;比如說把一個線性的數據不斷分成一棵二叉樹&#xff0c;也就是我們所說的線段樹&#xff0c;這樣我們就可以在logn的時限里做到修改和查詢。同理我們…

開始使用gitlab

不得不說&#xff0c;我真不是一個合格的程序猿&#xff0c;工作馬上兩年了&#xff0c;github和gitlab用的一點也不熟練&#xff0c;每次興致來了就搞幾下&#xff0c;可是每次都淺嘗輒止&#xff0c;不求甚解&#xff0c;時間一長&#xff0c;上一次練習的步驟就都記不起來了…