0

関数のwhileループを停止するのに問題がありKeyListenerます。10秒ごとに、Timer関数はであると宣言Activeしますfalse。しかし、それでも関数のwhileループは実行され続けます。KeyListener

ループが実行され続ける理由がわかりません。サイクルごとに、真であるかどうかをテストする必要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;
}
4

5 に答える 5

1

関数の引数であるため、呼び出しごとにKeyListenerActive の独自のコピーがあります。

この値を両方のスレッドで使用できるようにする必要があります。おそらくグローバルである必要があります。マークを付ける必要があります。そうしないとvolatile、コンパイラが値をレジスタに格納し、メイン メモリから読み取らないか、無限ループに陥る可能性があります。

より良い方法は、適切にスレッド同期されるある種のイベント変数または条件変数を使用することです。

于 2012-04-26T16:42:18.743 に答える
0

あなたが言った

Activeがtrueであるかどうかをテストする必要があるすべてのサイクルこれは当てはまらない場合があります。コンパイラは、そのブロックでActiveに対して何も行われていないため、その比較を最適化している可能性があります。Activeの揮発性指定子を使用して、コードがActiveのメモリ内の値を毎回チェックするようにすることをお勧めします。

volatile bool Active;

編集:また、誰かが指摘するように、Timer関数で何らかの理由でKeyListener(false)を呼び出します。Activeをfalseに設定する必要があります(コメントアウトされています)。

于 2012-04-26T16:42:58.493 に答える
0

同じ関数を呼び出す2つの異なるスレッドがあります。これにより、2つの異なる Active値が作成されます。

関数を再度呼び出しても、前の呼び出しのパラメーターの値には影響しません。

于 2012-04-26T16:40:18.430 に答える
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;
}
于 2012-04-26T16:40:41.603 に答える
0

Timer が呼び出している KeyListener 関数は、メイン関数呼び出しと同じではないと確信しています。メインスレッドでのみ KeyListener を呼び出してから、他のスレッドで、共有変数にアクセスして false に設定します。

于 2012-04-26T16:46:56.257 に答える