1.  继承QThread, 实现run()方法, 即可创建线程。

2. 实例1 代码

myThread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H #include <QThread> class myThread : public QThread //myThread 线程类
{
Q_OBJECT public:
myThread();
void setMessage(const QString &message);
void stop();
protected:
void run(); //复写run()方法,里面是线程 的 主体代码
private:
QString messageStr;
volatile bool stopped;
}; #endif // MYTHREAD_H

myThread.cpp

#include "myThread.h"
#include <QDebug> myThread::myThread()
{
stopped = false;
} void myThread::run() //实现run()方法, 隔1秒输出messageStr
{
while(!stopped)
{
qDebug() << messageStr << endl;
sleep(1);
}
stopped = false;
} void myThread::stop()
{
stopped = true;
} void myThread::setMessage(const QString &message)
{
messageStr = message;
}

dialog.h

#ifndef DIALOG_H
#define DIALOG_H #include <QDialog>
#include <QtGui>
#include "myThread.h" class Dialog : public QDialog
{
Q_OBJECT public:
Dialog(QWidget *parent = 0);
~Dialog(); protected:
void closeEvent(QCloseEvent *event); private slots:
void startOrStopThreadA();
void startOrStopThreadB(); private:
myThread threadA; //用线程类 实例化 线程对象
myThread threadB;
QPushButton *threadAButton;
QPushButton *threadBButton;
QPushButton *quitButton;
}; #endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
threadA.setMessage("A");
threadB.setMessage("B"); threadAButton = new QPushButton(tr("Start A"));
threadBButton = new QPushButton(tr("Start B"));
quitButton = new QPushButton(tr("Quit"));
quitButton->setDefault(true);
connect(threadAButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadA()));
connect(threadBButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadB()));
connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->addWidget(threadAButton);
hLayout->addWidget(threadBButton);
hLayout->addWidget(quitButton);
setLayout(hLayout);
} Dialog::~Dialog()
{
} void Dialog::startOrStopThreadA()
{
if( threadA.isRunning() )
{
threadA.stop(); //结束线程
threadAButton->setText(tr("Start A"));
}
else
{
threadA.start(); //thread.start()开始线程
threadAButton->setText(tr("Stop A"));
}
} void Dialog::startOrStopThreadB()
{
if( threadB.isRunning() )
{
threadB.stop();
threadBButton->setText(tr("Start B"));
}
else
{
threadB.start();
threadBButton->setText(tr("Stop B"));
}
} void Dialog::closeEvent(QCloseEvent *event) //当用户点击quit按键 或 这退出UI的时候,回调closeEvent函数
{
threadA.stop();
threadB.stop();
threadA.wait();
threadB.wait();
event->accept();
//qDebug("--log--");
}

3. 线程同步

QT线程同步的类有: QMutex, QReadWriteLock, QSemaphore, QWaitcondition.

QMutext互斥锁: 可以锁住一段代码,同一时间只能有一个线程访问。

或者用简化锁QMutexLocked类, 构造函数输入QMutex并将其锁住, 析构函数将其解锁。

QReadWriteLock类, 允许多个线程读共享资源,但是只允许一个线程写共享资源。

QSemaphore 信号量 互斥量, 解决 生产者--消费者 问题





 

4. 利用信号槽, 主线程和子线程通信,互相发送消息。

子线程向主线程发送 每隔一秒向主线程发送累加数字, 主线程按键信息发送到子线程。。

Thread.h

#ifndef THREAD_H
#define THREAD_H
#include <QThread> class Thread : public QThread
{
Q_OBJECT
private:
int number;
protected:
void run();
public:
Thread(QObject *parent=0);
~Thread();
signals:
void UpdateSignal(int num);
public slots:
void ResetSlot();
}; #endif // THREAD_H

Thread.cpp

#include "Thread.h"

Thread::Thread(QObject *parent)
{
number = 0;
} Thread::~Thread()
{
} void Thread::run()
{
while(1)
{
emit UpdateSignal(number); //发送更新信号给主线程,附带参数number
number++;
sleep(1);
}
} void Thread::ResetSlot()
{
number = 0;
emit UpdateSignal(number); //发送重置number信号
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H #include <QtGui>
#include "Thread.h" class Widget : public QWidget
{
Q_OBJECT public:
Widget(QWidget *parent = 0);
~Widget(); private:
QLabel *label;
QPushButton *startButton;
QPushButton *stopButton;
QPushButton *resetButton;
Thread *myThread;
int number; signals:
void ResetSignal(); public slots:
void clearSlot();
void startSlot();
void stopSlot();
void updateSlot(int num); }; #endif // WIDGET_H

widget.cpp

#include "widget.h"

Widget::Widget(QWidget *parent)
: QWidget(parent)
{
startButton = new QPushButton("start");
stopButton = new QPushButton("stop");
resetButton = new QPushButton("reset");
label = new QLabel("empty"); myThread = new Thread(); QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label);
layout->addWidget(startButton);
layout->addWidget(stopButton);
layout->addWidget(resetButton);
setLayout(layout); connect(stopButton, SIGNAL(clicked()), this, SLOT(stopSlot()));
connect(startButton, SIGNAL(clicked()), this, SLOT(startSlot()));
connect(resetButton, SIGNAL(clicked()), this, SLOT(clearSlot()));
connect(myThread, SIGNAL(UpdateSignal(int)), this, SLOT(updateSlot(int))); //子线程发信号给主线程,更新number
connect(this, SIGNAL(ResetSignal()), myThread, SLOT(ResetSlot())); //主线程发信号给子线程,重置number信号 resize(200, 200); } Widget::~Widget()
{ } void Widget::startSlot()
{
myThread->start();
} void Widget::stopSlot()
{
myThread->terminate();
} void Widget::updateSlot(int num)
{
label->setText(QString::number(num));
} void Widget::clearSlot()
{
emit ResetSignal(); //主线程发送重置信号 给 子线程
}

Qt QThread 线程创建,线程同步,线程通信 实例的更多相关文章

  1. 【Linux】一个简单的线程创建和同步的例子

    最近很多精力在Linux上,今天简单看了一下Linux上的线程和同步,其实不管windows还是Linux,OS层面的很多原理和概念都是相同的,很多windows之上的经验和概念完全可以移植到Linu ...

  2. Unix 环境高级编程---线程创建、同步、

    一下代码主要实现了linux下线程创建的基本方法,这些都是使用默认属性的.以后有机会再探讨自定义属性的情况.主要是为了练习三种基本的线程同步方法:互斥.读写锁以及条件变量. #include < ...

  3. java线程 — 创建和启动线程

    创建和启动线程,传统有两种方式: 方式1:继承Thread类: 方式2:实现Runnable接口: 线程类(java.lang.Thread):Thread类和Thread的子类才能称之为线程类.阅读 ...

  4. RT-thread线程创建:动态线程与静态线程

    本文介绍了如何创建一个动态线程和一个静态线程 RT-thread版本:RT-thread system 3.1.0 开发环境:MDK5 为了编程方便,创建了sample1.c文件,然后添加到工程中 话 ...

  5. Java基础加强之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

  6. Java基础之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

  7. Java基础学习总结(88)——线程创建与终止、互斥、通信、本地变量

    线程创建与终止 线程创建 Thread类与 Runnable 接口的关系 public interface Runnable {         public abstract void run(); ...

  8. Java 线程创建与常用方法

    进程与线程 进程 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 CPU,数据加载至内存.在指令运行过程中还需要用到磁盘.网络等设备.进程就是用来加载指令.管理内存.管理 IO ...

  9. RT-Thread学习笔记1-启动顺序与线程创建

    目录 1. 启动顺序 2. 堆范围 3. 线程创建 3.1 线程代码(入口函数) 3.2 线程控制块 3.3 线程栈 4. 系统滴答时钟 5. GPIO驱动架构操作IO 6. 线程优先级 & ...

  10. Java线程池二:线程池原理

    最近精读Netty源码,读到NioEventLoop部分的时候,发现对Java线程&线程池有些概念还有困惑, 所以深入总结一下 Java线程池一:线程基础 为什么需要使用线程池 Java线程映 ...

随机推荐

  1. poj1742

    Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 33998   Accepted: 11554 Descripti ...

  2. 【BZOJ4898】[Apio2017]商旅 分数规划+SPFA

    [BZOJ4898][Apio2017]商旅 Description 在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴.你被这个城市发达而美丽的市场所深深吸引,决定定居于此,做一个 ...

  3. 1119 机器人走方格 V2(组合)

    1119 机器人走方格 V2 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 M * N的方格,一个机器人从左上走到右下,只能向右或向下走.有多少种不同的走法?由于 ...

  4. C#关于AutoResetEvent的使用介绍----修正

    说明 之前在博客园看到有位仁兄发表一篇关于AutoResetEvent介绍,看了下他写的代码,看上去没什么问题,但仔细看还是能发现问题.下图是这位仁兄代码截图. 仁兄博客地址:http://www.c ...

  5. Linux中的特殊字符

    单引号: 在单引号中所有的特殊字符都没有特殊含义 双引号: 在双引号中 $ ` \ 三个字符表示,调用变量的值.引用命令.转义,其他特殊字符均没有特殊含义 反引号: 用反引号括起来的内容被当作系统命令 ...

  6. 006-重装yum

    报错情况: There was a problem importing one of the Python modulesrequired to run yum. The error leading ...

  7. 20170421 F110 常见问题

    F110常見問題以及處理方式 1. Vendor中沒有與F110中相同的Payment method 解決辦法: 在Vendor主檔中維護Payment method 2. 結報被Block 解決辦法 ...

  8. Java设计模式之《单例模式》及应用场景(转发:http://www.cnblogs.com/V1haoge/p/6510196.html)

    所谓单例,指的就是单实例,有且仅有一个类实例,这个单例不应该由人来控制,而应该由代码来限制,强制单例. 单例有其独有的使用场景,一般是对于那些业务逻辑上限定不能多例只能单例的情况,例如:类似于计数器之 ...

  9. Android 结束进程的方法forceStopPackage

    ActivityManager sd = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); Method method = Clas ...

  10. 通用TryParse

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Refle ...