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; }









좋은 웹페이지 즐겨찾기