当前位置:网站首页>Use and safe shutdown of qthread thread in QT
Use and safe shutdown of qthread thread in QT
2022-07-28 06:33:00 【Schoolmate Xiaotu!】
Preface
The first time I used threads, I couldn't achieve the desired effect , And to solve the problem of thread safe shutdown , Today, I saw a teacher talk about the use of threads , Although the understanding is not particularly profound , However, relevant precautions have been preliminarily summarized .
Environmental Science :
- qt5.12.12
- windows operating system
Use thread thinking :
- New thread class , Inherit QThread
- rewrite run() Method , Write complex programs in run In the implementation of , And set the cycle conditions ( Remember that some information says that threads must write loops )
- adopt start() Method to open the thread , adopt requestInterruption() Method sends an interrupt request to jump out of the loop condition , After jumping out of the loop, the thread ends
- Set the signal slot in the process class , Kill the thread when it ends
- In the destructor of the thread, you also need to add requestInterruption() Interrupt request , Prevent threads from closing safely when windows are forced to close
First list the weight lifting codes :( Remember to inherit classes QThread)
AudioThread.h file
void run() override;
AudioThread.cpp file
// Constructors
AudioThread::AudioThread(QObject *parent) : QThread(parent)
{
// When the thread ends (finished), Just call deleteLater Reclaiming memory
connect(this,&AudioThread::finished,this,[=](){
this->deleteLater();
qDebug()<<" Thread end ";
});
}
// Destructor
AudioThread::~AudioThread()
{
// When forcing the window to close , Threads can also be safely shut down
requestInterruption();
wait();
qDebug()<<" Destructor ";
}
void AudioThread::run()
{
..... Custom code
while(!isInterruptionRequested()){
// When no interrupt request is sent , Execution loop body
..... Custom code
}
..... Custom code
}
Open thread :
AudioThread *audio_thread=new AudioThread(this);
audio_thread->start();
Close thread :
audio_thread->requestInterruption();
audio_thread->wait(); // Wait for the thread to end before executing the following code
audio_thread=nullptr;
Complete code :( I call here through thread ffmpeg Realize audio recording , It looks a little complicated , You can only focus on important code , Don't copy and paste blindly , You need to configure before running ffmpeg)
AudioThread.h file
#ifndef AUDIOTHREAD_H
#define AUDIOTHREAD_H
#include <QObject>
#include <QThread>
class AudioThread : public QThread
{
Q_OBJECT
public:
explicit AudioThread(QObject *parent = nullptr);
~AudioThread();
private:
void run() override;
signals:
};
#endif // AUDIOTHREAD_H
AudioThread.cpp file
#include "audiothread.h"
#include <QDebug>
#include <QFile>
extern "C"{
// Equipment related API
#include <libavdevice/avdevice.h>
// Format dependent API
#include <libavformat/avformat.h>
// Tool related API( For example, error handling )
#include <libavutil/avutil.h>
// Code related API
#include <libavcodec/avcodec.h>
}
#ifdef Q_OS_WIN
// PCM File name of the file
#define FILENAME "E:/media/out.pcm"
#else
#define FILENAME "/Users/mj/Desktop/out.pcm"
#endif
AudioThread::AudioThread(QObject *parent) : QThread(parent)
{
// When the thread ends (finished), Just call deleteLater Reclaiming memory
connect(this,&AudioThread::finished,this,[=](){
this->deleteLater();
qDebug()<<" Thread end ";
});
}
AudioThread::~AudioThread()
{
// When forcing the window to close , Threads can also be safely shut down
requestInterruption();
wait();
qDebug()<<" Destructor ";
}
void AudioThread::run()
{
char *FMT_NAME="dshow";
const AVInputFormat *localAv_find_input_format = av_find_input_format(FMT_NAME);
if(!localAv_find_input_format){
qDebug()<<" Input format not found "<<FMT_NAME;
return;
}
qDebug()<<FMT_NAME;
AVFormatContext *ctx=nullptr;
char *device_name="audio= Microphone (Realtek High Definition Audio)";
int ret = avformat_open_input(&ctx,device_name,localAv_find_input_format,nullptr);
if(ret!=0){
char errbuf[1024];
av_strerror(ret,errbuf,sizeof(errbuf));
qDebug()<<" Failed to open device "<<ret<<errbuf;
return;
}
QFile file(FILENAME);
if(!file.open(QIODevice::WriteOnly)){
qDebug()<<" File opening failure "<<FILENAME;
avformat_close_input(&ctx);
return;
}
AVPacket *pkt = av_packet_alloc();
while(!isInterruptionRequested()){
// Collect data
ret = av_read_frame(ctx,pkt);
if(ret==0){
// Write... To the document
file.write((char *)pkt->data,pkt->size);
qDebug()<<" Recording in progress , File is being written ";
// Release resources
av_packet_unref(pkt);
}else if (ret == AVERROR(EAGAIN)) {
// Resources temporarily unavailable
continue;
}
else{
char errbuf[1024];
av_strerror(ret,errbuf,sizeof(errbuf));
qDebug()<<"av_read_frame error "<<errbuf<<sizeof (errbuf);
return;
}
av_packet_unref(pkt);
}
file.close();
// Release resources
av_packet_free(&pkt);
// Turn off the device
avformat_close_input(&ctx);
qDebug()<<" Recording completed successfully ";
return;
}
The main thread calls the sub thread :( You need to define global variables in advance AudioThread *audio_thread=nullptr;bool is_record,is_abnormal;)
void MainWindow::on_pushButton_clicked()
{
if(!is_record){
audio_thread=new AudioThread(this);
audio_thread->start();
// Prevent forced closing of windows , The thread cannot exit normally
connect(audio_thread,&AudioThread::finished,audio_thread,[=](){
ui->pushButton->setText(" Start recording ");
is_record=false;
if(is_abnormal){
qDebug()<<" Thread ended abnormally ";
}
});
qDebug()<<" Start recording ";
ui->pushButton->setText(" The end of the recording ");
is_record=true;
}else{
is_abnormal=false;
audio_thread->requestInterruption();
audio_thread->wait();
audio_thread=nullptr;
qDebug()<<" The end of the recording ";
ui->pushButton->setText(" Start recording ");
is_record=false;
}
}
Program effect :

Feeling QThread There are still many precautions in use , There will be new understandings in the future
It's not easy to code words , If this blog is helpful to you , Please praise the collection , Thank you very much ! There is something wrong
边栏推荐
- Vscode中,无法打开源文件 “Adafruit_GFX.h“
- Monitor the CPU temperature of raspberry pie 4B installed with esxi on ARM
- VS Code 基础配置与美化
- Introduction to Perl (IX) quotation
- 【学习笔记】编码能力
- Listener
- IP地址的五大分类
- Pytorch learning note 4 - automatic calculation of gradient descent autograd
- What are the common English questions in the postgraduate interview?
- ICC2(一)Preparing the Design
猜你喜欢

JSON笔记

Cronbach’s α? Kmo coefficient? Factor load? The most understandable course of questionnaire reliability and validity analysis in history!!! (SPSS and AMOS)

Matlab simulation of radar imaging 2 - pulse compression and windowing

Trouble encountered in cable testing -- a case study of a manufacturer?

qt自定义滑动按钮(美观且使用方便)

qt设置加载界面的几种方法

Cautious speculation about fusion on Apple silicon

Transformer self attention mechanism and complete code implementation

Systemmediasize startup option added in esxi 7.0 update 1C

雷达成像 Matlab 仿真 1 —— LFM信号及其频谱
随机推荐
Talking about fluke optical cable certification? What is CFP? What is OFP?
set_multicycle_path
Matlab simulation of radar imaging 4 - range resolution analysis
详解安装msdn 2015及其注意事项
What happens when MySQL tables change from compressed tables to ordinary tables
Cronbach’s α? Kmo coefficient? Factor load? The most understandable course of questionnaire reliability and validity analysis in history!!! (SPSS and AMOS)
Synopsys Multivoltage Flow
Machine learning note 5 - logistic regression
VS Code 基础配置与美化
vi和vim命令
Pytorch learning note 4 - automatic calculation of gradient descent autograd
MySQL安装与使用
mixup_ ratio
Paper artifact vs code + latex + latex workshop
How to calibrate dsx2-8000? Calibration process?
我的注解笔记
MATLAB signal processing
Talk about the "hybrid mode" of esxi virtual switch and port group
ICC2分析时序的神器 analyze_design_violations
小程序:生命周期