2.暂停、停止线程

1.停止线程方法
interrupt()、 stop()、interrupt()、return();
2.为何用interrupt 而不用stop,
因stop方法直接强行停止过于暴力,直接停止,当前线程不会执行完毕,后续清理过程不到位,且对锁定的数据进行解锁,导致数据得不到同步处理,使得数据不一致,容易出错。
而在使用interrupt方法后,不会终止一个正在运行的线程,还需加入判断才会完成线程的最终停止;
3.线程是否终止的判断
1)this.interrupted():测试当前线程是否中断,执行后将状态标志清除为false;
2)this.isInterrupted: 测试线程是否已经中断,执行后不清除状态标志。
4.interrupt()方法的使用
1).异常法
在用this.interrupted()方法判断已经是停止状态后;throw new InterruptedException(),抛出异常,然后在try{}catch{}进行停止线程后的操作;
2).interrupt()搭配return;
在用this.interrupted()方法判断已经是停止状态后使用return使线程停止,但仍推荐异常法,因return不会抛出错误,使得不清楚是什么时候线程终止的,终止后的线程也无法进行一个更合理的处理
5.暂停线程
1).suspend()方法暂停线程;resume()方法继续开始线程
缺点:独占、不同步;两个方法使用不当,容易造成公共的同步对象的独占,使得其他线程无法访问公共的同步对象;
独占:如在循环调用println打印时候进行suspend方法停止,后面的所有println打印都将无法进行,因println是一个同步方法,而suspend将其暂停了
不同步:容易出现因线程暂停导致的数据不同步,如赋值中途使用了suspend暂停,而此时又有用户在调用该数据,而调用后,该线程有resume()开始运行,最后所调用到的数据就会出现严重不一致。

下面是一个简单的代码示例,实现了上述功能要求: ```c++ #include <QMainWindow> #include <QLabel> #include <QThread> #include <QTimer> #include <QMutex> #include <QPixmap> #include <QVBoxLayout> #include <QPushButton> class ImageLoader : public QThread { public: ImageLoader(QObject *parent = nullptr) : QThread(parent), m_stop(false) {} virtual void run() override { while (!m_stop) { // 加锁,保证线程安全 m_mutex.lock(); // 读取图片文件 // ... // 更新图片 emit imageUpdated(m_pixmap); // 解锁 m_mutex.unlock(); // 等待一段时间 msleep(100); } } void stop() { m_stop = true; } void setImage(const QPixmap &pixmap) { // 加锁,保证线程安全 m_mutex.lock(); m_pixmap = pixmap; // 解锁 m_mutex.unlock(); } signals: void imageUpdated(const QPixmap &pixmap); private: QMutex m_mutex; QPixmap m_pixmap; bool m_stop; }; class MainWindow : public QMainWindow { public: MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) { QWidget *centralWidget = new QWidget(this); setCentralWidget(centralWidget); QVBoxLayout *layout = new QVBoxLayout(centralWidget); m_leftLabel = new QLabel(this); m_rightLabel = new QLabel(this); m_leftLabel->setAlignment(Qt::AlignCenter); m_rightLabel->setAlignment(Qt::AlignCenter); layout->addWidget(m_leftLabel); layout->addWidget(m_rightLabel); QHBoxLayout *buttonLayout = new QHBoxLayout(); QPushButton *startButton = new QPushButton("Start", this); QPushButton *pauseButton = new QPushButton("Pause", this); QPushButton *stopButton = new QPushButton("Stop", this); buttonLayout->addWidget(startButton); buttonLayout->addWidget(pauseButton); buttonLayout->addWidget(stopButton); layout->addLayout(buttonLayout); // 创建图片加载线程 m_loader = new ImageLoader(this); connect(m_loader, &ImageLoader::imageUpdated, this, &MainWindow::updateImage); // 点击开始按钮,启动线程 connect(startButton, &QPushButton::clicked, this, [this]() { m_loader->start(); }); // 点击暂停按钮,暂停线程 connect(pauseButton, &QPushButton::clicked, this, [this]() { m_loader->stop(); }); // 点击结束按钮,停止线程 connect(stopButton, &QPushButton::clicked, this, [this]() { m_loader->stop(); m_loader->wait(); }); } virtual ~MainWindow() { delete m_loader; } private: QLabel *m_leftLabel; QLabel *m_rightLabel; ImageLoader *m_loader; void updateImage(const QPixmap &pixmap) { m_leftLabel->setPixmap(pixmap); m_rightLabel->setPixmap(pixmap); } }; ``` 在主窗口中,我们创建了两个 `QLabel`,用于显示读取的图片。同时,我们创建了一个 `ImageLoader` 类,继承自 `QThread`,用于在后台线程中读取图片并更新主窗口的显示。我们通过 `QMutex` 来保证线程安全,避免多个线程同时访问共享数据。在主窗口中,我们通过三个按钮来控制图片加载线程的启动、暂停停止
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值