在主執行緒中慎用WaitForSingleObject (WaitForMultipleObjects) --代替方法:MsgWaitForMultipleObjects
下面的程式碼我除錯了將近一個星期,你能夠看出什麼地方出了問題嗎?
執行緒函式:
while ( ! bTerminate)
{
// 從一個連結串列中讀取資訊並且插入到CListCtrl中
// CListCtrl的控制代碼是通過執行緒引數傳遞進來的 for (;;)
{
ReadInfoFromList();
InsertToCListCtrl();
}
}
}
主執行緒中使用CreateThread啟動執行緒。
當想終止子執行緒時,在主執行緒中:
bTerminate = TRUE;
WaitForSingleObject(threadHandle, INFINITE);
可是,以執行到WaitForSingleObject,子執行緒就Crash了。
為什麼呢?
問題原因:
後來我終於在InsertItem的反彙編中發現瞭如下的程式碼
call dword ptr [
可見,InsertItem是必須藉助訊息迴圈來完成任務的。如果我們在主執行緒中WaitForSingleObject了,必然導致主執行緒阻塞,也就導致了訊息迴圈的阻塞,最終導致工作執行緒Crash掉了*_*
解決方案:
為了解決在主執行緒中Wait的問題,微軟專門設計了一個函式MsgWaitForMultipleObjects,這個函式即可以等待訊號(thread,event,mutex等等),也可以等待訊息(MSG)。即不論有訊號被激發或者有訊息到來,此函式都可以返回。呵呵,那麼我的解決辦法也就出來了。
將上面的WaitForSingleObject用下面的程式碼替換:
while
{
DWORD result ;
MSG msg ;
result = MsgWaitForMultipleObjects(1, &readThreadHandle,
FALSE, INFINITE, QS_ALLINPUT);
if (result == (WAIT_OBJECT_0))
{
break;
}else{
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
DispatchMessage(&msg);
}
}
總結:
如果在工作執行緒中有可能涉及到了訊息驅動的API,那麼不能在主執行緒中使用WaitForSingleObject一類函式,而必須使用上述的方案。
相關推薦
在主執行緒中慎用WaitForSingleObject (WaitForMultipleObjects) --代替方法:MsgWaitForMultipleObjects
下面的程式碼我除錯了將近一個星期,你能夠看出什麼地方出了問題嗎? 執行緒函式: DWORD WINAPI ThreadProc( while ( ! bTerminate) { // 從一個連結串列中讀取資訊並且插入到CListCtrl中
Android面試:主執行緒中的Looper.loop()一直無限迴圈為什麼不會造成ANR?(轉)
引子: 正如我們所知,在android中如果主執行緒中進行耗時操作會引發ANR(Application Not Responding)異常。 造成ANR的原因一般有兩種: 只有當應用程式的UI執行緒響應超時才會引起ANR,超時產生原因一般有兩種 1. 當前的事件沒有機會
android主執行緒中Looper.loop()為什麼不會造成程式ANR
程式入口為ActivityThread的main方法,原始碼如下: frameworks/base/core/java/android/app/ActivityThread.java public static void main(String[] args) { S
Qt中通過訊號和槽在子執行緒和主執行緒中進行資料傳遞
QT中兩個執行緒之間進行自定義型別資料傳遞 兩個執行緒中進行資料傳遞時,傳遞的資料放到佇列中(queue),所以在這個過程中,需要在傳遞前將資料拷貝、儲存到佇列中;為了儲存這些引數,Qt需要construct、destruct、copy這些物件,為了讓Qt知道
[轉]Android限制只能在主執行緒中進行UI訪問的實現原理
目錄 Android限制只能在主執行緒中進行UI訪問 Thread的實現 Android Thread 的構造方法 Android Thread 的start()方法 如何在我們自己的程式碼中去檢測當前Thread是不是UI執
WebTool 網頁資訊獲取,可在主執行緒中呼叫
WebTool.java package sci.tool; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.URL; import java.net.U
主執行緒中呼叫執行緒的start()
public class Quest implements Runnable { int b = 100; public synchronized void m1() throws Exception { System.out.println("en
Handler訊息傳遞機制(子執行緒中傳遞new Handler和主執行緒中new Handle傳遞訊息)
> 子執行緒中更新UI new Thread(new Runnable() { @Override public void run() { Looper.prepare();
Android中為什麼主執行緒不會因為Looper.loop()方法造成阻塞
很多人都對Handler的機制有所瞭解,如果不是很熟悉的可以看看我 如果看過原始碼的人都知道,在處理訊息的時候使用了Looper.loop()方法,並且在該方法中進入了一個死迴圈,同時Looper.loop()方法是在主執行緒中呼叫的,那麼為什麼沒有造成阻
Android主執行緒中延時處理
Android對UI主執行緒開啟了實時監聽,Activity Manager和WindowManager系統服務一旦監聽到主執行緒超過10秒沒有響應操作,就會丟擲ANR,所以,在UI主執行緒中不能直接呼叫Thread.sleep方法去延時,超過10秒就根本不會執
Android 幾種非同步方式,解決主執行緒中遇到的卡頓
起因: 當我們的UI越來越複雜的時候,或者說某個業務需要大量的計算的時候,我們的主執行緒會消耗大量的資源去計算,這個時候,我們的Activity或者說fragmemt等UI頁面就會出現卡頓,乃至ANR。總結一下,就是我們直接在主執行緒(UI執行緒)中,做耗時操作,就會造成卡
關於主執行緒中自動建立的Looper的思考:主執行緒中Looper中的輪詢死迴圈為何沒有阻塞主執行緒
Android中UI執行緒會自動給我們建立一個looper,但是looper中的loop方法是個死迴圈.為什麼我們在UI執行緒中寫的程式碼為何都能順利執行?為什麼沒有引起ANR呢? Looper的部分原始碼: /** * Initial
handle.post 跳到主執行緒中執行
package com.example.che; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.widget.T
主執行緒中的Looper.loop()一直無限迴圈為什麼不會造成ANR?
引子: 正如我們所知,在android中如果主執行緒中進行耗時操作會引發ANR(Application Not Responding)異常。 造成ANR的原因一般有兩種: 當前的事件沒有機會得到處理(即主執行緒正在處理前一個事件,沒有及時的完成或者looper被某種原因阻塞住了)當前的事件正在處理,但沒有
Handler.post(Runable),Runable是執行在主執行緒中的。
在Android中可以通過handler方法完成資料的執行緒間的傳遞,但一定要將handler得到的資料通過loop傳遞到主執行緒再更新UI嗎?其實也可以直接使用handler設計的post方法進行
Handler寫在主執行緒中,使用Message傳遞訊息
Runnable是一個介面,Thread是Runnable的子類。 Message Message 是線上程之間傳遞的訊息,它可以在內部攜帶少量的資訊,用於在不同執行緒之間交換資料。 Ha
Looper機制:主執行緒中利用handler向工作執行緒傳送訊息
注意:由主執行緒向非UI執行緒中傳送訊息的時候,非UI執行緒需要先新增訊息佇列,然後處理訊息迴圈。 (1).預設情況下android中新誕生的執行緒是沒有開啟訊息迴圈的。(主執行緒除外,主執行緒系統會自動為其建立Looper物件,開啟訊息迴圈。)
NSTimer直接使用需要在主執行緒中使用
NSTimer 的 scheduledTimerWithTimeInterval 方法使用時需要在主執行緒中使用否則不會執行的。 1. NSRunLoopCommonModes和Timer 當使用NSTimer的scheduledTimerWithTime
用Handler的post()方法來傳遞執行緒中的程式碼段到主執行緒中執行
package com.kale.handler; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android
主執行緒中Thread.Sleep()是否會導致ANR
前言: 1.對Thread.sleep(long duration)的認知。 &