[問題] C++多執行緒執行問題

作者: englishman (葉師父)   2018-09-13 10:38:19
開發平台(Platform): (Ex: Win10, Linux, ...)
Win10, i7 四核心處理器
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
VS2015
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
OpenCV
問題(Question):
各位先進大家好,我製作了一個透過WiFi傳輸讀取外部device傳來的影像然後即時顯示到
PC UI的程式,程式分為UI層及kernel層,kernel層是一個包成DLL函式,裡面有開執行緒
(可以設定開幾個執行緒),不斷地從kernel撈資料,然後透過callback方式傳到UI層即時
顯示。而為什麼撈資料要用多執行緒,是因為撈完資料後需要進行後處理,所以希望用多執
行緒的方式進行影像後處理,以免僅使用單執行緒後處理花太多時間卡頓畫面顯示。
測試後,我遇到的問題是,當我使用超過一個執行緒去跑的時候,畫面會有嚴重的卡頓,可是
當我在執行緒執行的loop裡面加入"printf()"函式,畫面就變得流暢多了??想請教先進有
甚麼多執行緒在設計的時候CPU資源方面我沒注意到的嗎?還是其他問題?? 十分感謝!!
餵入的資料(Input):
影像資料, 更新率大約8張/秒
預期的正確結果(Expected Output):
多執行緒抓取WiFi資料資料後能夠流暢地即時顯示在 UI
錯誤結果(Wrong Output):
沒有加入printf(),畫面卡頓,有加了printf(),畫面變流暢
程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔)
class ThreadFunc
{
public:
HANDLE hThread;
bool bExitThread;
DWORD dwThreadID;
unsigned char uchNo;
bool bIsRunning;
public:
ThreadFunc(HANDLE _hThread, bool _bExitThread, DWORD _dwThreadID,
unsigned char _uchNo, bool _bIsRunning) : hThread(_hThread),bExitThread
(_bExitThread), dwThreadID(_dwThreadID), uchNo(_uchNo), bIsRunning
(_bIsRunning) {}
ThreadFunc() { }
~ThreadFunc(){ }
void LoopCycle();
static DWORD WINAPI CoreThread(void* Param)
{
ThreadFunc* This = (ThreadFunc*)Param;
This->ThreadStart();
return NULL;
}
void Start()
{
hThread = CreateThread(NULL, 0, CoreThread, (void*) this, 0,
&dwThreadID);
}
void Exit()
{
if (hThread)
{
bExitThread = true;
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
hThread = NULL;
}
}
DWORD ThreadStart(void)
{
while (!bExitThread)
{
LoopCycle(); // 不斷地去撈影像資料並做後處理
printf("Thread No. is %d\n\n", uchNo); // 有加這一行,
//程式會順很多;沒有這一
//行會卡頓
}
return 0;
}
};
ThreadFunc* g_pcThreadFunc = new ThreadFunc[4]; // 開 > 1 個執行緒, 假設
// 4 個
補充說明(Supplement):
作者: s4300026 (s4300026)   2018-09-13 14:34:00
sleep(0); ?
作者: VSei (Chaos)   2018-09-13 14:48:00
Polling太快造成卡頓? 經驗是改成callback比較不會卡
作者: eye5002003 (下一夜)   2018-09-13 14:51:00
直覺就是sleep一點點就好,別讓任何thread吸乾資源
作者: dontfindme (Hsiu)   2018-09-13 14:59:00
直覺:給Thread一點休息時間,或是改成callback(比較好)
作者: englishman (葉師父)   2018-09-17 14:23:00
感謝各位先進回答,加了Sleep()有效果,但需要加到Sleep(40)才會變得不會頓。另外,有試過從底層callback上去然後想讓UI直接畫圖,但沒有透過類似Android API 的RunOnUIThread()這種function似乎直接畫是不可行的,請問在Windows下面有類似RunOnUIThread這種切到mainThread然後去畫Form1的圖的function或機制嗎?感謝!
作者: easyman (oops)   2018-09-18 20:34:00
應該是wifi 有收到東西, 再判斷是否完整thread 再用 WaitForSingleObject() 等待 完整data再開始處理, 處理完進 queue , main thread 來畫

Links booklink

Contact Us: admin [ a t ] ucptt.com