首页 > 其他分享 >qt线程间通信

qt线程间通信

时间:2024-12-06 16:57:12浏览次数:10  
标签:qt Worker 间通信 工作 线程 信号 include

在 Qt 中,线程间通信通常通过信号与槽(Signal & Slot)机制来实现。Qt 的信号与槽机制使得不同线程之间能够安全地传递数据而不必直接操作共享内存,这也减少了多线程编程中的许多复杂性。线程间通信的常见方式包括使用信号与槽机制、事件机制、以及 QMutex 等同步工具。

  1. 信号与槽机制(Signal and Slot)
    Qt 的信号与槽机制是线程间通信最常见的方式。通过信号与槽,线程之间可以传递数据或者通知其他线程发生了某些事情。

线程间信号与槽通信的步骤:
主线程:可以创建工作线程,工作线程通过发射信号将结果发送回主线程。
工作线程:可以将处理完成的结果通过信号发射给主线程,主线程使用槽函数接收信号并进行后续处理。
示例:线程间通信
以下是一个简单的 Qt 示例,演示了主线程与工作线程之间的通信。

  1. Worker 类(工作线程)
    首先,我们需要创建一个继承自 QThread 或者使用 QRunnable 的工作线程类,这个类将负责执行后台任务,并通过信号与主线程通信。
cpp
#include <QThread>
#include <QObject>
#include <QDebug>

class Worker : public QObject
{
    Q_OBJECT

public:
    Worker() {}

public slots:
    void doWork() {
        // 模拟耗时操作
        qDebug() << "工作线程开始执行";

        // 假设这是一段耗时的操作
        QThread::sleep(2);

        // 发射信号,通知主线程操作完成
        emit workDone("工作完成");
    }

signals:
    void workDone(const QString &result);  // 发射信号给主线程
};
2. MainWindow 类(主线程)
在主线程中,我们创建一个工作线程,并连接信号与槽。

cpp
#include <QMainWindow>
#include <QPushButton>
#include <QThread>
#include <QDebug>
#include "worker.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent)
    {
        QPushButton *startButton = new QPushButton("开始工作", this);
        startButton->setGeometry(50, 50, 150, 50);

        // 创建工作线程
        Worker *worker = new Worker();
        QThread *thread = new QThread(this);

        // 将工作线程对象移到子线程中
        worker->moveToThread(thread);

        // 连接信号与槽
        connect(startButton, &QPushButton::clicked, worker, &Worker::doWork);  // 按钮点击时开始工作
        connect(worker, &Worker::workDone, this, &MainWindow::onWorkDone);  // 工作完成后接收信号
        connect(thread, &QThread::started, worker, &Worker::doWork);  // 子线程启动时执行工作

        // 启动线程
        thread->start();
    }

private slots:
    void onWorkDone(const QString &result) {
        // 收到工作完成的信号后,处理返回的结果
        qDebug() << result;
    }
};
3. main.cpp
创建 Qt 应用和主窗口,并启动应用。

cpp

#include <QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

代码解析:
工作线程 (Worker 类):

doWork() 槽函数是工作线程的主要任务,它执行耗时操作(在这里模拟了 2 秒的延时)。
workDone() 信号在任务完成后发射,返回任务结果。
主窗口 (MainWindow 类):

主窗口有一个按钮,点击按钮后会启动工作线程。
主窗口通过 connect 语句将按钮的点击信号与工作线程的 doWork() 槽连接,当按钮被点击时,工作线程开始工作。
当工作完成后,工作线程通过信号 workDone() 通知主线程,并传递结果,主线程通过 onWorkDone() 槽函数接收并处理结果。
2. 事件机制(Event Loop)
另一种常见的线程间通信方式是通过事件机制。Qt 提供了一个基于事件队列的机制,可以让线程通过 QCoreApplication::postEvent() 函数将事件发送到其他线程的事件队列,并通过 event() 函数处理。

  1. QMutex 和 QWaitCondition(用于线程同步)
    如果需要在多个线程之间同步共享数据的访问,可以使用 QMutex 来加锁,保证线程安全,防止竞争条件。
cpp
QMutex mutex;
mutex.lock();
// 访问共享资源
mutex.unlock();

QWaitCondition 可以用于线程之间的通知机制,使得一个线程可以等待另一个线程的信号。

总结:
Qt 提供了多种线程间通信方式,最常见的是通过 信号与槽机制 来实现线程间的通信,尤其是主线程和工作线程之间的通信。通过这个机制,可以避免直接访问共享数据,从而减少了线程同步问题和死锁的风险。

标签:qt,Worker,间通信,工作,线程,信号,include
From: https://blog.csdn.net/jjjxxxhhh123/article/details/144296032

相关文章

  • 监测各个核上cpu上的线程是内核线程还是用户线程,处于内核态还是用户态的方法
    一、背景这篇博客是对于之前的 内核模块注册调度的tracepoint的回调,逻辑里判断当前线程处于内核态还是用户态的方法-CSDN博客 的补充,在 内核模块注册调度的tracepoint的回调,逻辑里判断当前线程处于内核态还是用户态的方法-CSDN博客 里的方法,我们在那篇博客的最后提示了只......
  • QT - QOverload说明及示例
    在QT中,通常我们建立信号槽时信号和槽传递的参数是对应的,允许槽的函数比信号的函数少,但是排列顺序不能变。当信号的参数被重载或者信号参数与槽函数的参数不一致时,需要指定本次connect时信号使用的参数或者将信号使用的参数强转,这就用到了信号重载。比如常用的QComboBox类中的&QC......
  • 爬取小说资源的Python实践:从单线程到多线程的效率飞跃
    爬取小说资源的Python实践:从单线程到多线程的效率飞跃前提声明爬虫应遵守目标网站的robots.txt协议,尊重版权和用户隐私。本代码仅供学习和研究使用,不得用于商业用途。请确保在合法合规的前提下使用本代码。本代码所爬取的小说资源为公开可下载的内容。目录引言环境准备......
  • Qt5.15新建类报错是大小写问题吗?
    新建类小写,报错.cpp中头文件缺失,或者构造函数缺失kimi答案如果自定义的类名为Command,并且它是小写的,那么它默认情况下并不会继承自QObject。在Qt中,继承自QObject的类可以获得许多Qt框架提供的特性,比如信号和槽机制、事件处理、以及动态属性系统等。如果你希望Command类拥有这些......
  • 【Linux】:多线程(互斥 && 同步)
    ......
  • Java多线程相关面试题整理
    ​1.什么是线程和进程?进程:是指一个在内存中运行的应用程序,常见的app都是一个个进程。进程具有自己独立的内存空间,一个进程可以有多个线程;线程:是指进程中的一个执行任务的单元,负责执行当前进程中程序的执行,一个进程至少有一个线程,一个进程内的多个线程见可共享数据。线程与......
  • bash shell多线程方案
    一般多线程#!/bin/bashfunctiontask{echo"Startingtask$1"sleep$1echo"Task$1completed"}#启动多个后台任务task1&task2&task3&#等待所有后台任务完成waitecho"Alltaskscompleted"线程池的实现#!/bin/bash......
  • IoTDB通过MQTT存储 windows
    IoTDB内置MQTT服务端IoTDB默认关闭MQTT服务,需要修改配置文件默认MQTT配置文件修改 enable_mqtt_service=true enable_mqtt_service=true mqtt_port=1883 配置信息参考使用MQTTX工具测试MQTTX配置信息 MQTTX发送消息"device":数据库路径"timestamp":时间戳......
  • .NET Core 线程池(ThreadPool)底层原理浅谈
    https://www.cnblogs.com/lmy5215006/p/18566995 文提到,创建线程在操作系统层面有4大无法避免的开销。因此复用线程明显是一个更优的策略,切降低了使用线程的门槛,提高程序员的下限。.NETCore线程池日新月异,不同版本实现都有差别,在.NET6之前,ThreadPool底层由C++承载。在之后......
  • Qt - Json数据解析
     json数据格式:{"name":"Alice","age":30,"isStudent":false,"courses":[{"courseName":"Mathematics","credits":3,"ins......