从GUI实现基本线程管理-启动,停止,暂停



我正在寻找如何在Windows平台上使用c++从GUI管理工作线程的常用方法。

问题很简单,我有一个基本的用户界面,有3个按钮:开始,暂停和停止。第一个按钮启动一个线程,该线程在给定的文件夹中查找图像,并逐像素地反转它们的颜色。用户界面还可以选择在一个矩形的、不可编辑的文本区域中显示由工作线程的事件生成的日志消息。

本文描述了实践中最早使用的一种解决方案:CodeProject:使用工作线程

作者写道:

当您有任何类型的变量可以从一个变量修改时线程,并且其修改必须在另一个线程中检测到,则必须将其声明为volatile

如果没有原子变量这样的结构,如何在最新的编译器上实现相同的功能。

更新:

  • 我知道上面这篇文章已经过时了,我想让人们也看看多线程是如何从早期发展起来的会很有趣。但我把这篇文章和这个问题联系起来的主要原因是因为它的引用,它很简单,表达得很好。当我开始考虑应用程序中的专用线程时,它形成了经常出现的问题。
  • 我不期望在答案中对c++中提出的问题有任何具体的解决方案。一般来说,解决这个问题的常见方法是什么?我希望这个问题在实践中以这样或那样的形式经常遇到。

您需要一个类来管理线程状态,当然还需要一些基本代码来运行std::线程。如下所示

#include <iostream>
#include <thread>
#include <mutex>
class Bar
{
public:
Bar() 
{
goOn = true;
suspended = false;
}
void worker()
{
int count = 0;
while (continue())
{
if (!isSuspened())
{
std::cout << "counting ... " << count << 'n';
count++;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
bool isSuspened()
{
std::lock_guard<std::mutex> lock(mtx);
return suspended;
}
void suspend(bool b)
{
std::lock_guard<std::mutex> lock(mtx);
suspended = b;
}
void terminate()
{
std::lock_guard<std::mutex> lock(mtx);
goOn = false;
}
bool continue()
{
std::lock_guard<std::mutex> lock(mtx);
return goOn;
}
private:
bool goOn;
bool suspended;
std::mutex mtx;
};
int main()
{
Bar bar;
// Create and execute the thread
std::thread thread(&Bar::worker, &bar); // Pass 10 to member function
std::string asw;
while (true)
{
std::cout << "Enter 's' to suspend the thread, 'r' to resume or 't' to terminate: ";
std::cin >> asw;
if (asw == "s")
bar.suspend(true);
else if (asw == "r")
bar.suspend(false);
else if (asw == "t")
{
bar.terminate();
break;
}
}
thread.join();
return 0;
}
注意使用std::互斥锁来同步对控制线程执行的变量的访问。这对于避免由于从两个不同线程并发访问变量而导致的奇怪行为非常重要

查看std::stop_token的示例代码。它需要c++ 20,但看看现在使用标准c++是多么简单。你甚至可以忽略join;std::jthread破坏join

最新更新