Qt 控制线程的顺序执行(使用QWaitCondition,并且线程类的run函数里记得加exec(),使得线程常驻)
背景
项目中用到多线程,对线程的执行顺序有要求:
A.一个线程先收数据
B.一个线程处理数据
C.一个线程再将处理后的数据发送出去
要求三个线程按照ABC的顺序循环执行。
思路
子类化多线程方法
重写子类的run函数,在run函数内用while(1)来常驻线程,循环体内通过检查全局变量来判断是否到自己执行,不是自己线程则跳过,是自己线程执行完后改变全局标志位。通过全局标志位来控制线程的执行顺序。所以需要一个全局变量来标记当前应当执行的线程,同时用一个互斥量来保护该全局变量。
movetoThread多线程方法
为每个线程设计相应的方法类,将生成的方法类对象移入到对应的线程内,方法类的方法必须通过信号和槽的方式来触发。
本文采用第二种思路来实现线程的顺序执行
QWaitConditon简介
线程如何睡眠?
调用QWaitCondition的wait函数将使得调用它的线程进入睡眠状态
线程如何醒来?
在另外的线程中调用QWaitConditon的wakeOne或者wakeAll方法将唤醒等待它的线程
实现过程
先定义全局变量
QWaitCondition condition_input; //数据收线程的条件变量,控制线程睡眠和唤醒
QWaitCondition condition_process;//数据处理线程的条件变量,控制线程睡眠和唤醒
QWaitCondition condition_output;//数据发线程的条件变量,控制线程睡眠和唤醒
//保护条件变量,防止多线程同时访问条件变量
QMutex mutex_input;
QMutex mutex_process;
QMutex mutex_output;
1
2
3
4
5
6
7
8
2.实现接收数据的方法的槽函数
void input::work()
{
while(1)//使得线程常驻
{
qDebug()<<"input1";
mutex_process.lock();
condition_process.wakeOne();//唤醒下一次的数据处理线程
mutex_process.unlock();
mutex_input.lock();
condition_input.wait(&mutex_input);//睡眠当前的收线程
mutex_input.unlock();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
3.实现处理数据的方法的槽函数
void process::work()
{
while (1)
{
qDebug()<<"process2";
mutex_output.lock();
condition_output.wakeOne();//唤醒下一次的发线程
mutex_output.unlock();
mutex_process.lock();
condition_process.wait(&mutex_process);//睡眠当前处理线程
mutex_process.unlock();
}
}
void process::threadSleep()
{
qDebug()<<QThread::currentThreadId();
mutex_process.lock();
condition_process.wait(&mutex_process);//睡眠当前处理线程
mutex_process.unlock();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
4.实现发送数据的方法的槽函数
void output::work()
{
while (1)
{
qDebug()<<"output3";
mutex_input.lock();
condition_input.wakeOne();//唤醒下一次的收线程
mutex_input.unlock();
mutex_output.lock();
condition_output.wait(&mutex_output);//睡眠当前的发线程
mutex_output.unlock();
}
}
void output::threadSleep()
{
qDebug()<<QThread::currentThreadId();
mutex_output.lock();
condition_output.wait(&mutex_output);//睡眠当前的发线程
mutex_output.unlock();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
5.main函数中的最终实现
input_thread = new inputThread();
process_thread = new processThread();
out_thread = new outputThread();
//开启线程
input_thread ->start();
process_thread ->start();
out_thread ->start();
//生成方法对象
data_input = new input();
data_process = new process();
data_output = new output();
//移入线程
data_input->moveToThread(input_thread);
data_process->moveToThread(process_thread);
data_output->moveToThread(out_thread);
//使得数据处理和数据发送线程睡眠的槽函数和按键1的点击信号关联
connect(this,SIGNAL(click1()),data_process,SLOT(threadSleep()));
connect(this,SIGNAL(click1()),data_output,SLOT(threadSleep()));
//使得三个线程的work槽函数和按键1的点击信号关联
connect(this,SIGNAL(click2()),data_input,SLOT(work()));
connect(this,SIGNAL(click2()),data_process,SLOT(work()));
connect(this,SIGNAL(click2()),data_output,SLOT(work()));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
使用方法
先触发click1信号,使得数据处理线程和数据发送线程睡眠;再触发click2信号,使得三个线程按照既定的顺序ABC循环执行。
输出结果
input1
process2
output3
input1
process2
output3
input1
process2
output3
input1
process2
output3
1
2
3
4
5
6
7
8
9
10
11
12
注意事项
线程类的run函数里记得加exec(),使得线程常驻
---------------------
作者:蜗牛在听雨
来源:CSDN
原文:https://blog.csdn.net/omg_orange/article/details/82388243
版权声明:本文为博主原创文章,转载请附上博文链接!
Qt 控制线程的顺序执行(使用QWaitCondition,并且线程类的run函数里记得加exec(),使得线程常驻)的更多相关文章
- C#之使用AutoResetEvent实现线程的顺序执行
前几天一朋友问我如何实现线程的顺序执行,说真的,虽然看过CLR这本书,也把线程部分拜读了两遍,但是这个问题出来之后还是没有一个思路.今天在搜索资料的时候无意中再次看到AutoResetEvent这个东 ...
- 【Java并发】线程的顺序执行
/** * 问题:有线程a.b.c,如何让它们顺序执行? * 方式一:可用Join()方法实现 * 方式二:可用newSingleThreadExecutor() * Created by Smile ...
- Qt QThread两种方式的使用:1-继承QThread重写run函数; 2- 继承QObject并moveToThread && 消息和槽在线程和依附线程间的传递
2019年08月18日起笔 方式一:继承QThread重写run函数 MyThread.h ----------------------------------- ... class MyThread ...
- 3.创建线程的第二种写法,继承threading.Tread类,重写run方法
#创建线程的第二种写法 #1.自定义一个类 #2.继承Thread #3.重写run()方法 import threading,time,random class MyThread(threading ...
- 三个线程abc顺序执行
1.使用synchronized悲观锁(秋招阿里的一个笔试题,应该写的比较复杂,然后就没有然后了o(╥﹏╥)o) public class ThreadThreadp { private int fl ...
- java 多线程 实现多个线程的顺序执行
场景 编写一个程序,启动三个线程,三个线程的name分别是A,B,C:,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC... 使用 synchronized 实现 public cla ...
- Jmeter-Critical Section Controller(临界区控制器)(还没看,是一个控制请求按顺序执行的东东)
The Critical Section Controller ensures that its children elements (samplers/controllers, etc.) will ...
- Java中如何保证线程顺序执行
只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的.如果只是创建三个线程然后执行,最后的执行顺序是不可预期的.这是因为在创建完线程之后,线程执行的开始时间取决于CPU何时分配时间片,线程 ...
- Python流程控制-1 顺序执行
流程控制指的是代码运行逻辑.分支走向.循环控制,是真正体现我们程序执行顺序的操作.流程控制一般分为顺序执行.条件判断和循环控制. 顺序执行 Python代码在执行过程中,遵循下面的基本原则: 普通语句 ...
随机推荐
- <UIKit>关于剪贴板共享数据
http://blog.sina.com.cn/s/blog_45e2b66c010102h9.html 上面这篇文章将剪贴板的使用方法基本上已经讲清楚了,参考这篇文章,再加上一个使用剪贴板共享数据 ...
- mysql数据库中,flush logs语句的作用是什么呢?
需求描述: 今天在研究mysql数据库的备份和恢复,用到了flush logs这个SQL语句. 所以,在此进行测试,并且记录该SQL语句的作用. 概念描述: 在mysql数据库,如果数据库启动的时候, ...
- android 开发者资源下载地址记录(转+补充)
https如果无法下载的话将下面的:https://dl-ssl 部分改为 http://dl (1)Android SDK (Android SDK主安装包,包含SDK Manager.AVD Ma ...
- vue 组件库
iView https://www.iviewui.com/ Radon UI https://luojilab.github.io/radon-ui/#!/ Element http://eleme ...
- html5 file 自定义文件过滤
使用 acctpe属性即可 示例: gif,jpg <input type="file" name="pic" accept="image/gi ...
- C语言的基本构成
C语言的基本构成 知识点:C语言的注释:关键字:书写风格:常量和变量 重要程度:★★★★ 1.C语言的良好风格 用C语言编写的程序,称为C语言源程序,简称C程序. 本节将通过一个简单的C程序例子,向大 ...
- Solr4.0+IKAnalyzer中文分词安装
1.依赖: JDK1.6,Tomcat 5.5,Solr 4.0.0,IKAnalyzer 2012FF Tomcat虽然不是必须,但觉得上生产环境的话,还是得用Tomcat,便于统一管理和监控. T ...
- php 升级后 htmlspecialchars 返回空 的解决方案
今天将php版本升级到5.3.0以上(我升级到php5.4.13)的版本后发现一个问题 htmlspecialchars 函数返回为空.查了资料后,发现新版本对htmlspecialchars这个函数 ...
- Android AndroidManifest.xml配置文件
AndroidManifest.xml配置文件介绍本质:AndroidManifest.xml是整个应用的主配置清单文件.包含:该应用的包名.版本号.组件.权限等信息.作用:记录该应用的相关配置信息. ...
- 【PHPstudy】安装Composer
1 正确安装phpstudy,启动,右下角 右键选择 cms命令行 2 输入以下命令, 查看是否正确输出版本号. php -v 3 打开命令行并依次执行下列命令安装最新版本的 Composer: ph ...