2012-04-26 115 views
0

我無法停止KeyListener函數中的while循環。 Timer函數每10秒鐘聲明Activefalse。但KeyListener函數中的while循環仍然在運行。通過使用線程停止while循環C++

我想不通爲什麼循環繼續運行;每個週期它應測試Active是否爲真,如果不是(因爲在10秒後應該關閉),則循環不應該運行。但它確實如此。

void KeyListener(bool Active) 
{ 
    cout << Active << endl; //debug 
    while (Active==true){ 
     cout << "loop still running." << endl; //debug 
     Sleep(100); 
     for (int i=8;i<=190;i++){ 
      if (GetAsyncKeyState(i) == -32767){ 
       KeyWrite(i); // (turns the numbers into characters) 
      }  
     } 
    } 
} 

void Timer(void* pParams){ 
    while (true){ 
     Sleep(10000); 
     KeyListener(false); // Active = false 
     cout << "KeyListener(false)" << endl; // debug 
    } 
} 

int main() 
{ 
    _beginthread(Timer, 0, NULL); 
    KeyListener(true); 

    return 0; 
} 
+0

我鏈接了代碼,因爲我不知道如何/沒有特權嵌入它。 – Rob 2012-04-26 16:36:21

+1

在運行到線程之前,先了解C++中函數的工作原理。 – Dani 2012-04-26 16:39:05

+1

你正在調用這個函數兩次。你不停止第一個你正在創建另一個立即停止。 – twain249 2012-04-26 16:40:04

回答

0

10秒後,單獨的線程調用KeyListener(false)。這爲設置了Active false,該函數調用。但是,原來的KeyListener(true)函數調用是不受影響。新的調用無法影響舊調用的非靜態局部變量。


volatile bool Active; 

void KeyListener() 
{ 
    cout << Active << endl; //debug 
    while (Active==true){ 
     cout << "loop still running." << endl; //debug 
     Sleep(100); 
     for (int i=8;i<=190;i++){ 
      if (GetAsyncKeyState(i) == -32767){ 
       KeyWrite(i); // (turns the numbers into characters) 
      }  
     } 
    } 
} 

void Timer(void* pParams){ 
    while (true){ 
     Sleep(10000); 
     Active = false 
     cout << "Active = false" << endl; // debug 
    } 
} 

int main() 
{ 
    Active = true; 
    _beginthread(Timer, 0, NULL); 
    KeyListener(); 

    return 0; 
} 
+0

謝謝你的幫助山姆。你能告訴我是否可以從另一個線程中斷一個循環?再次感謝! – Rob 2012-04-26 16:43:30

+0

Rob,@ZanLynx答案看起來像是指向正確的方向。如果你需要更多的幫助,評論他的答案,將會觀看。 – 2012-04-26 16:46:25

+0

嗯,我把主動變成一個易變的布爾值,(它應該使它成爲一個全局的布爾?),但仍然沒有效果。 – Rob 2012-04-26 16:59:18

0

您有兩個不同的線程調用相同的函數。這創造了兩個不同的Active值。

再次調用函數不會影響先前調用的參數值。

+0

同樣的問題給你,是否有可能中斷從另一個線程的循環?謝謝你的幫助! – Rob 2012-04-26 16:44:29

1

每個您的通話以KeyListener都有自己的活動副本,因爲它是一個函數參數。

您需要使這個值可用於兩個線程。它應該可能是一個全球性的。它需要標記爲volatile,否則編譯器會將該值存儲到寄存器中,並且從不從主存儲器讀取它,否則它甚至會將其變爲無限循環。

一個更好的方法是使用某種事件或條件變量,它將正確線程同步。

+0

非常感謝,我一定會看到 – Rob 2012-04-26 16:45:58

0

你說

它應該測試閹主動每個週期是真實 這可能並非如此。編譯器可以優化該比較,因爲它沒有看到該塊中的任何內容正在執行。我建議你使用Active的volatile修飾符來確保代碼每次都檢查內存中的Active值。

volatile bool Active; 

編輯: 此外,有人指針移出,在你的定時器功能調用的KeyListener(假)的某些原因。您應該將Active設置爲false(已將其註釋掉)。

0

我很確定你正在調用你的KeyListener函數並不是同一個主函數調用。只在主線程中調用KeyListener,然後在其他線程中,讓它訪問共享變量並將其設置爲false。