使用线程C++停止循环

Stop while loop from by using a thread C++

本文关键字:循环 C++ 线程      更新时间:2023-10-16

我在停止KeyListener函数中的while循环时遇到问题。每隔 10 秒,Timer 函数就会声明Active false。但 KeyListener 函数中的while循环仍然保持运行。

我不知道为什么循环一直运行;每个周期它都应该测试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;
}

KeyListener的每个调用都有自己的 Active 副本,因为它是一个函数参数。

您需要使此值对两个线程都可用。它可能应该是一个全球性的。它需要标记为volatile或者编译器会将值存储到寄存器中,并且永远不会从主存储器读取它,或者甚至可能将其变成无限循环。

更好的方法是使用某种事件或条件变量,这些变量将正确线程同步。

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;
}

您有两个不同的线程调用同一个函数。这将创建两个不同的Active值。

再次调用函数不会影响上一次调用的参数值。

你说

它应该测试的每个周期是否有效是真的 情况可能并非如此。 编译器可能会优化该比较,因为它看不到在该块中对 Active 执行任何操作。 我建议您使用 Active 的易失说明符,以确保代码每次都会检查 Active 的内存值。

volatile bool Active;

编辑:此外,当有人指出时,在您的 Timer 函数中,出于某种原因,您调用了 KeyListener(false)。 您应该将"活动"设置为 false(已注释掉)。

我很确定计时器正在调用的KeyListener函数与主函数调用不同。仅在主线程中调用 KeyListener,然后在另一个线程中调用它,让它访问共享变量并将其设置为 false。