QT-멀티스레드 지식(예: 멀티스레드 다운로드 소설)
10718 단어 QT
QThread의 루틴 클래스를 계승하여run 방법을 실현하고 헤더 파일을 포함합니다
#include
현재 스레드 id 가져오기
currentThreadId()
스레드 수면(1초)
sleep(1) 또는 msleep(1000) 또는 msleep(1000000)
스레드 우선 순위
setPriority()
노정 양도
yieldCurrentThread()
스레드 종료
terminate()
스레드 켜기
start()
스레드 대기
wait()
2. 라인 상호 배척
QMutex mt, lock 및 unlock을 통해 제어
QMutexLocker locker(&mt)
//생산자 소비자 모델, 즉 신호 모델
QSemaphore freeBytes(80); QSemaphore usedBytes(0);
//대기와 깨우기를 이용하여 제어
3. 다선정 다운로드 소설
1. mainwindow 파일
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#pragma execution_character_set("utf-8")
#include
#include
#include
#include
#include
#include "leaderthread.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_viewFile_clicked();
void on_startDown_clicked();
void onFinished(QNetworkReply* reply);
public slots:
void logWrite(QString log);
void finishDown();
private:
Ui::MainWindow *ui;
QString mvpath;
QString module;
QString bqgUrl;
QString bookname;
QList pageList;
QNetworkAccessManager *netManager;
QString getSubStr(QString str,QString start_str,QString end_str,qint32 start_len,qint32 end_len);
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
bqgUrl = "http://www.biquge.com/";
netManager = new QNetworkAccessManager(this);
connect(netManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(onFinished(QNetworkReply*)));
logWrite("www.biquge.com/xxx/(xxx )");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_viewFile_clicked()
{
QString dir = QFileDialog::getExistingDirectory(this," :",".",QFileDialog::ShowDirsOnly);
ui->mvpath->setText(dir);
}
void MainWindow::on_startDown_clicked()
{
mvpath = ui->mvpath->text();
if(mvpath.isEmpty()){
QMessageBox::warning(this," "," !");return;
}
module = ui->module->text();
if(module.isEmpty()){
QMessageBox::warning(this," "," !");return;
}
netManager->get(QNetworkRequest(QUrl(bqgUrl+module)));
ui->startDown->setEnabled(false);
}
void MainWindow::onFinished(QNetworkReply* reply)
{
pageList.clear();
QByteArray arr = reply->readAll();
QString content(arr);
QRegExp rx("/"+module+"/[0-9]{7,9}.html");
qint32 startPos = 0;
qint32 pos = content.indexOf(rx,startPos);
while( pos >= 0){
pageList.append(rx.cap(0));
pos = content.indexOf(rx,pos + rx.matchedLength());
}
reply->deleteLater();
LeaderThread * leader = new LeaderThread();
leader->setList(pageList);
leader->setParam(this,bqgUrl+module+"/",mvpath);
leader->setBookName(getSubStr(content,"","",51,0));
leader->start();
}
void MainWindow::logWrite(QString log)
{
ui->log->append(log);
}
QString MainWindow::getSubStr(QString str,QString start_str,QString end_str,qint32 start_len,qint32 end_len)
{
qint32 pos_start = str.indexOf(QRegExp(start_str),0);
if(pos_start == -1){
return "";
}
qint32 pos_end = str.indexOf(QRegExp(end_str),pos_start);
if(pos_end == -1){
return "";
}
return str.mid(pos_start+start_len,pos_end-end_len-pos_start-start_len);
}
void MainWindow::finishDown()
{
ui->startDown->setEnabled(true);
}
2、 LeaderThread
#ifndef LEADERTHREAD_H
#define LEADERTHREAD_H
#include
#include "mainwindow.h"
#include "downloadthread.h"
#include
#pragma execution_character_set("utf-8")
class LeaderThread : public QThread
{
Q_OBJECT
public:
LeaderThread();
void setList(QList& list);
void setParam(QMainWindow* wnd,QString baseUrl,QString path);
void setBookName(QString bookname);
signals:
void sendLog(QString log);
void finishDown();
protected:
void run();
void openMuchTread(qint32 n,qint32 start_pos);
private:
QList m_list;
QMainWindow* wnd;
QString baseUrl;
QString path;
QString bookname;
};
#endif // LEADERTHREAD_H
#include "leaderthread.h"
LeaderThread::LeaderThread()
{
}
void LeaderThread::run()
{
QDir dir(path+"/tmp");
if(!dir.exists()){
dir.mkdir(path+"/tmp");
}
QString filename = path + "/" + bookname + ".txt";
if(QFile::exists(filename)){
QFile::remove(filename);
}
connect(this,SIGNAL(sendLog(QString)),wnd,SLOT(logWrite(QString)));
connect(this,SIGNAL(finishDown()),wnd,SLOT(finishDown()));
qint32 listSize = m_list.size();
for(qint32 i = 0;i < listSize ; i=i+25){
if((listSize-i)>0 && (listSize-i) < 25){
openMuchTread(listSize-i,i);
}else{
openMuchTread(25,i);
}
}
QFile file(filename);
if(!file.open(QFile::WriteOnly|QFile::Truncate)){
sendLog(" , ");return;
}
for(QString item : m_list){
QFile tmpfile(path + "/tmp/" + item);
if(!tmpfile.open(QFile::ReadOnly)){
sendLog(" :"+item);return;
}
file.write(tmpfile.readAll());
file.write("\r
\r
\r
");
tmpfile.close();
QFile::remove(path + "/tmp/" + item);
sendLog(" :"+item);
}
file.close();
dir.rmdir(path + "/tmp");
QString logInfo;
logInfo = QString(" , %1 ").arg(m_list.size());
sendLog(logInfo);
finishDown();
quit();
}
void LeaderThread::setList(QList& list)
{
for(QString item : list){
int pos = item.indexOf(QRegExp("/"),1);
QString newStr = item.mid(pos+1,7);
if(!m_list.contains(newStr))
m_list.append(newStr);
}
qSort(m_list.begin(),m_list.end());
}
void LeaderThread::setParam(QMainWindow* wnd,QString baseUrl,QString path)
{
this->wnd = wnd;
this->baseUrl = baseUrl;
this->path = path;
}
void LeaderThread::openMuchTread(qint32 n,qint32 start_pos)
{
QList downlist;
for(qint32 i = 0 ;i < n ;++i){
QString page = m_list.at(start_pos + i);
DownloadThread* downThread = new DownloadThread(wnd,baseUrl,page,path);
downlist.append(downThread);
downThread->start();
}
for(DownloadThread* tr : downlist){
tr->wait(10000);
}
downlist.clear();
}
void LeaderThread::setBookName(QString bookname){
this->bookname = bookname;
}
3, 단일 다운로드 스레드 DownloadThread#ifndef DOWNLOADTHREAD_H
#define DOWNLOADTHREAD_H
#include
#include
#include "mainwindow.h"
#pragma execution_character_set("utf-8")
class DownloadThread : public QThread
{
Q_OBJECT
public:
DownloadThread();
DownloadThread(QMainWindow* wnd,QString baseUrl,QString page,QString path);
protected:
void run();
QString getContent(QString html);
QString getSubStr(QString str,QString start_str,QString end_str,qint32 start_len,qint32 end_len);
signals:
void sendLog(QString log);
private:
QMainWindow* wnd;
QString baseUrl;
QString page;
QString path;
};
#endif // DOWNLOADTHREAD_H
#include "downloadthread.h"
DownloadThread::DownloadThread()
{
}
DownloadThread::DownloadThread(QMainWindow* wnd,QString baseUrl,QString page,QString path)
{
this->wnd = wnd;
this->baseUrl = baseUrl;
this->page = page;
this->path = path;
}
void DownloadThread::run()
{
connect(this,SIGNAL(sendLog(QString)),wnd,SLOT(logWrite(QString)));
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(baseUrl + page + ".html")));
QEventLoop eventLoop;
connect(reply,SIGNAL(finished()),&eventLoop,SLOT(quit()));
eventLoop.exec();
QByteArray arr = reply->readAll();
QFile file(path + "/tmp/" + page);
if(!file.open(QFile::WriteOnly))
{
sendLog(" "+page+" ");
return;
}
QString html(arr);
QString content = getContent(html);
file.write(content.toUtf8());
file.close();
delete reply;
delete manager;
quit();
}
QString DownloadThread::getSubStr(QString str,QString start_str,QString end_str,qint32 start_len,qint32 end_len)
{
qint32 pos_start = str.indexOf(QRegExp(start_str),0);
if(pos_start == -1){
return "";
}
qint32 pos_end = str.indexOf(QRegExp(end_str),pos_start);
if(pos_end == -1){
return "";
}
return str.mid(pos_start+start_len,pos_end-end_len-pos_start-start_len);
}
QString DownloadThread::getContent(QString html)
{
QString title = getSubStr(html,"","",34,0);
QString content = getSubStr(html,"","",43,70);
content.replace(QRegExp(" ")," ");
content.replace(QRegExp("
"),"\r
");
sendLog(" :" + title);
return title + "\r
\r
" + content;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
간편한 채팅 시스템 - 메시지 전달 서버메시지 전송 서버는 메시지 대기열에서 온 데이터를 받아들여 디코딩, 식별 등을 하고 마지막으로 분류를 나눈다.예를 들어 채팅 시스템은 같은 그룹과 같은 세션의 정보를 같은 그룹 서비스로 전송한다(물론 아직 같은 그룹...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.