国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

QT基礎(chǔ)篇(12)QT5多線程

這篇具有很好參考價(jià)值的文章主要介紹了QT基礎(chǔ)篇(12)QT5多線程。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

在任何一門語言中,多線程都是一個(gè)相對其他方面比較重要的點(diǎn),這里面的知識體系很龐大,同步和異步之間的處理方式,以及IO多路復(fù)用等等各種進(jìn)行性能優(yōu)化的方面,在往上層一點(diǎn)我們不可能一直進(jìn)行系統(tǒng)層次的調(diào)用,這樣太費(fèi)時(shí)間也太麻煩,就到設(shè)計(jì)模式這里,比如反應(yīng)器(Reactor)模式,再者多線程對代碼的敏感程度較高,很對細(xì)微的改變可能會(huì)帶來意向不到的效果,這更要求我們對于我們寫的代碼有更深次的理解,不僅僅是代碼本身,還要求代碼執(zhí)行階段鎖遇到的各種問題,這就非??简?yàn)一個(gè)程序員的功底。

1.多線程及簡單實(shí)例

QT5的多線程可以使用QtConcurrent和QThread兩種方式來實(shí)現(xiàn)。

  1. 使用QtConcurrent: QtConcurrent提供了一種簡單的方式來編寫并行的代碼。通過使用QtConcurrent::run()函數(shù),可以在后臺(tái)線程中執(zhí)行一個(gè)函數(shù)。
#include <QtConcurrent>
#include <QDebug>

void myFunction()
{
    qDebug() << "Running in background thread";
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QtConcurrent::run(myFunction);

    qDebug() << "Running in main thread";

    return a.exec();
}
  1. 使用QThread: QThread類提供了一個(gè)線程對象,可以通過繼承QThread來實(shí)現(xiàn)自定義的線程類。
#include <QThread>
#include <QDebug>

class MyThread : public QThread
{
public:
    void run() override
    {
        qDebug() << "Running in background thread";
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyThread thread;
    thread.start();

    qDebug() << "Running in main thread";

    return a.exec();
}

以上示例中,myFunction()函數(shù)或者M(jìn)yThread類的run()函數(shù)會(huì)在后臺(tái)線程中執(zhí)行,而主線程會(huì)繼續(xù)執(zhí)行下面的代碼。

需要注意的是,當(dāng)使用QThread時(shí),不要直接調(diào)用run()函數(shù),而是通過start()函數(shù)來啟動(dòng)線程。另外,在多線程編程中,需要注意線程安全性和共享資源的競爭問題。

2.多線程控制
2.1互斥量

在QT中,可以使用QMutex(互斥量)來控制多個(gè)線程對共享資源進(jìn)行互斥訪問,以避免競爭條件和數(shù)據(jù)損壞。

下面是一個(gè)使用QMutex的簡單示例:

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QMutex>

QMutex mutex;

int sharedData = 0;

class MyThread : public QThread
{
public:
    void run() override
    {
        mutex.lock();
        
        // 訪問共享資源
        for (int i = 0; i < 10000; i++) {
            sharedData++;
        }
        
        mutex.unlock();
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyThread thread1;
    MyThread thread2;

    thread1.start();
    thread2.start();

    thread1.wait();
    thread2.wait();

    qDebug() << "sharedData: " << sharedData;

    return a.exec();
}

在這個(gè)示例中,我們創(chuàng)建了兩個(gè)線程來遞增sharedData變量的值。為了確保對sharedData的訪問是互斥的,我們使用了mutex對象。在run()函數(shù)中,我們使用mutex.lock()來鎖定互斥量,然后執(zhí)行對共享資源的訪問,最后使用mutex.unlock()來解鎖互斥量。

這樣就保證了同時(shí)只有一個(gè)線程可以訪問共享資源,避免了數(shù)據(jù)損壞。

2.2信號量

在QT中,可以使用QSemaphore(信號量)來控制多個(gè)線程對資源的訪問。信號量允許指定一個(gè)資源的數(shù)量,線程可以通過獲取和釋放信號量來控制對資源的訪問。

下面是一個(gè)使用QSemaphore的簡單示例:

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QSemaphore>

QSemaphore semaphore(1); // 初始化信號量為1

int sharedData = 0;

class MyThread : public QThread
{
public:
    void run() override
    {
        semaphore.acquire(); // 等待獲取信號量

        // 訪問共享資源
        for (int i = 0; i < 10000; i++) {
            sharedData++;
        }

        semaphore.release(); // 釋放信號量
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyThread thread1;
    MyThread thread2;

    thread1.start();
    thread2.start();

    thread1.wait();
    thread2.wait();

    qDebug() << "sharedData: " << sharedData;

    return a.exec();
}

在這個(gè)示例中,我們創(chuàng)建了兩個(gè)線程來遞增sharedData變量的值。為了確保對sharedData的訪問是互斥的,我們使用了一個(gè)信號量semaphore,并將其初始化為1。

在每個(gè)線程的run()函數(shù)中,我們首先使用semaphore.acquire()來等待獲取信號量。一旦線程獲取到信號量,它就可以訪問共享資源,進(jìn)行對sharedData的遞增操作。最后,線程使用semaphore.release()來釋放信號量。

由于我們將信號量初始化為1,所以只有一個(gè)線程能夠獲取到信號量,而另一個(gè)線程必須等待。這樣就確保了對共享資源的訪問是互斥的。

2.3線程等待及喚醒

在Qt中,可以使用QWaitCondition類來控制線程的等待和喚醒。QWaitCondition提供了一個(gè)條件變量,可以讓線程在某個(gè)條件滿足時(shí)等待,并在條件滿足時(shí)被喚醒。

下面是一個(gè)使用QWaitCondition的簡單示例:

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QWaitCondition>
#include <QMutex>

QWaitCondition condition;
QMutex mutex;
bool ready = false;

class MyThread : public QThread
{
public:
    void run() override
    {
        mutex.lock();
        while (!ready) {
            condition.wait(&mutex);
        }
        mutex.unlock();

        qDebug() << "Thread " << QThread::currentThread() << " is running";
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyThread thread1;
    MyThread thread2;

    thread1.start();
    thread2.start();

    // 模擬一段耗時(shí)操作
    QThread::currentThread()->sleep(2);

    mutex.lock();
    ready = true;
    condition.wakeAll();
    mutex.unlock();

    thread1.wait();
    thread2.wait();

    return a.exec();
}

在這個(gè)示例中,我們創(chuàng)建了兩個(gè)線程來執(zhí)行一段耗時(shí)操作。在主線程中,我們首先將ready變量設(shè)置為true,然后調(diào)用condition.wakeAll()來喚醒所有等待在條件變量上的線程。

在每個(gè)線程的run()函數(shù)中,我們首先使用mutex.lock()來鎖定互斥量。然后,線程進(jìn)入一個(gè)循環(huán),使用condition.wait(&mutex)來等待條件變量。只有當(dāng)條件變量滿足時(shí),線程才會(huì)被喚醒。一旦被喚醒,線程會(huì)打印一條消息,并繼續(xù)執(zhí)行。

這樣,我們就實(shí)現(xiàn)了一種控制線程等待和喚醒的機(jī)制。主線程通過設(shè)置條件變量并喚醒等待的線程,實(shí)現(xiàn)了線程的同步。

3.多線程應(yīng)用
3.1服務(wù)器端編程

在Qt中,可以使用QTcpServer來實(shí)現(xiàn)多線程的服務(wù)器端編程。下面是一個(gè)簡單的示例:

#include <QCoreApplication>
#include <QTcpServer>
#include <QTcpSocket>
#include <QThreadPool>
#include <QDebug>

class MyThread : public QThread
{
public:
    MyThread(qintptr socketDescriptor, QObject *parent = nullptr)
        : QThread(parent), m_socketDescriptor(socketDescriptor)
    {
    }

    void run() override
    {
        QTcpSocket socket;
        if (!socket.setSocketDescriptor(m_socketDescriptor))
        {
            emit error(socket.error());
            return;
        }

        qDebug() << "New connection:" << socket.peerAddress().toString() << ":" << socket.peerPort();

        // 處理客戶端請求
        QByteArray requestData = socket.readAll();
        qDebug() << "Received data:" << requestData;

        // 響應(yīng)客戶端請求
        QByteArray responseData = "Hello from server!";
        socket.write(responseData);
        socket.waitForBytesWritten();

        // 斷開連接
        socket.disconnectFromHost();
        socket.waitForDisconnected();

        qDebug() << "Connection closed:" << socket.peerAddress().toString() << ":" << socket.peerPort();
    }

signals:
    void error(QAbstractSocket::SocketError socketError);

private:
    qintptr m_socketDescriptor;
};

class MyServer : public QTcpServer
{
    Q_OBJECT
public:
    MyServer(QObject *parent = nullptr)
        : QTcpServer(parent)
    {
    }

protected:
    void incomingConnection(qintptr socketDescriptor) override
    {
        MyThread *thread = new MyThread(socketDescriptor, this);
        connect(thread, &MyThread::finished, thread, &MyThread::deleteLater);
        connect(thread, &MyThread::error, this, &MyServer::handleError);
        thread->start();
    }

private slots:
    void handleError(QAbstractSocket::SocketError socketError)
    {
        qDebug() << "Socket error:" << socketError;
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyServer server;
    if (!server.listen(QHostAddress::Any, 1234))
    {
        qDebug() << "Failed to start server!";
        return -1;
    }

    qDebug() << "Server started, listening on port 1234...";

    return a.exec();
}

#include "main.moc"

在這個(gè)示例中,我們創(chuàng)建了一個(gè)MyServer類,繼承自QTcpServer。在incomingConnection()函數(shù)中,每次有新的連接到來時(shí),我們創(chuàng)建一個(gè)新的MyThread線程來處理該連接。

MyThread類繼承自QThread,覆蓋了run()函數(shù)。在run()函數(shù)中,我們創(chuàng)建了一個(gè)QTcpSocket對象,并使用setSocketDescriptor()函數(shù)將其與傳入的套接字描述符關(guān)聯(lián)起來。然后,我們處理客戶端的請求,讀取請求數(shù)據(jù),對數(shù)據(jù)進(jìn)行處理,并向客戶端返回響應(yīng)數(shù)據(jù)。最后,斷開連接。

在main()函數(shù)中,我們創(chuàng)建了一個(gè)MyServer對象,并通過調(diào)用listen()函數(shù)來啟動(dòng)服務(wù)器。通過傳入監(jiān)聽的IP地址和端口號,來監(jiān)聽對應(yīng)的地址和端口。如果listen()成功啟動(dòng)服務(wù)器,則會(huì)在控制臺(tái)顯示對應(yīng)的提示信息。

這樣,我們就實(shí)現(xiàn)了一個(gè)多線程的服務(wù)器端程序。每次有新的連接到來時(shí),都會(huì)創(chuàng)建一個(gè)新的線程來處理該連接,實(shí)現(xiàn)了服務(wù)器的并發(fā)處理能力。

3.2客戶端編程

在Qt中,可以使用QThread來實(shí)現(xiàn)多線程的客戶端編程。下面是一個(gè)簡單的示例:

#include <QCoreApplication>
#include <QTcpSocket>
#include <QDebug>
#include <QThread>

class MyThread : public QThread
{
public:
    MyThread(QObject *parent = nullptr)
        : QThread(parent)
    {
    }

    void run() override
    {
        QTcpSocket socket;
        socket.connectToHost("127.0.0.1", 1234);
        
        if(!socket.waitForConnected())
        {
            qDebug() << "Failed to connect to server!";
            return;
        }

        // 發(fā)送請求
        QByteArray requestData = "Hello from client!";
        socket.write(requestData);
        socket.waitForBytesWritten();

        // 接收響應(yīng)
        QByteArray responseData = socket.readAll();
        qDebug() << "Received data: " << responseData;

        // 斷開連接
        socket.disconnectFromHost();
        socket.waitForDisconnected();
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyThread thread;
    thread.start();

    return a.exec();
}

#include "main.moc"

在這個(gè)示例中,我們創(chuàng)建了一個(gè)MyThread類,繼承自QThread。在run()函數(shù)中,我們創(chuàng)建了一個(gè)QTcpSocket對象,并使用connectToHost()函數(shù)連接到服務(wù)器端。如果連接成功,則發(fā)送請求數(shù)據(jù),并等待響應(yīng)數(shù)據(jù)的返回。最后,斷開連接。

在main()函數(shù)中,我們創(chuàng)建了一個(gè)MyThread對象,并調(diào)用start()函數(shù)來啟動(dòng)線程。

這樣,我們就實(shí)現(xiàn)了一個(gè)多線程的客戶端程序。通過在獨(dú)立的線程中與服務(wù)器建立連接、發(fā)送請求和接收響應(yīng),實(shí)現(xiàn)了客戶端的并發(fā)操作能力。文章來源地址http://www.zghlxwxcb.cn/news/detail-815546.html

到了這里,關(guān)于QT基礎(chǔ)篇(12)QT5多線程的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Qt5.12】Qt5.12安裝教程[通俗易懂]

    【Qt5.12】Qt5.12安裝教程[通俗易懂]

    Qt5.12下載網(wǎng)址: Index of /archive/qt/5.12/5.12.2 選擇Windows平臺(tái), Linux和Mac平臺(tái)類似 下載好之后的安裝包: Step1: 雙擊安裝包, 稍等片刻, 然后點(diǎn)擊next Step2: 如果沒有賬號, 則選擇skip Step3: Qt設(shè)置歡迎界面, 選擇下一步 Step4: 選擇安裝路徑 Step5: 選擇組件, 然后選擇下一步 Step6: 同意許可協(xié)議

    2024年02月13日
    瀏覽(26)
  • 【Qt】Qt5.12.12安裝教程詳解

    【Qt】Qt5.12.12安裝教程詳解

    Qt(官方發(fā)音 [kju:t],音同 cute)是一個(gè)跨平臺(tái)的 C++ 開發(fā)庫,主要用來開發(fā)圖形用戶界面(Graphical User Interface,GUI)程序,當(dāng)然也可以開發(fā)不帶界面的命令行(Command User Interface,CUI)程序。 Qt 是純 C++ 開發(fā)的,所以學(xué)好 C++ 非常有必要,對于不了解 C++ 的讀者,我建議先閱讀《

    2024年02月13日
    瀏覽(24)
  • 【Qt 學(xué)習(xí)之路】記一次安裝 Qt5.12.12 安卓環(huán)境的失敗案例

    【Qt 學(xué)習(xí)之路】記一次安裝 Qt5.12.12 安卓環(huán)境的失敗案例

    安裝的 Qt5.12.12 版本 Qt下載地址: https://download.qt.io/archive/qt/ 安裝Qt,可能會(huì)碰到“qt.tool.perl”安裝程序錯(cuò)誤,可以看我的記錄解決: Qt開發(fā) 之 安裝程序錯(cuò)誤–安裝進(jìn)程(qt.tool.perl)的解決辦法 JDK NDK SDK openssl 注意組合套件的版本和Qt的版本要對應(yīng)起來!同時(shí),安裝路徑不可

    2024年02月19日
    瀏覽(24)
  • Qt5.14.2 Qt多線程實(shí)戰(zhàn)演練,全面掌握線程同步和線程池最佳實(shí)踐

    多線程編程是每個(gè)開發(fā)者必須掌握的基本能力之一。在上一篇文章中,我們學(xué)習(xí)了Qt多線程編程的理論知識。本文將切入實(shí)戰(zhàn),提供多個(gè)案例代碼,幫助你徹底掌握Qt的多線程編程實(shí)踐技巧。 案例1: 使用QThread執(zhí)行耗時(shí)任務(wù) 這個(gè)案例演示了如何通過繼承QThread和重寫run()函數(shù),在

    2024年03月20日
    瀏覽(25)
  • QT5.12在windows上邊的安裝

    使用國內(nèi)鏡像源在線安裝QT(2023.3.25更新)_qt國內(nèi)鏡像_Iotfsd的博客-CSDN博客 先下載 STEP1:下載qt online installer Index of /official_releases/online_installers (qt.io) STEP1:使用國內(nèi)鏡像源在線安裝Qt ? ? qDPass(12MB/s) 在《STEP1》下載的“qt-unified-windows-x64-4.5.2-online.exe”目錄進(jìn)入CMD,然后運(yùn)行下面

    2024年02月12日
    瀏覽(26)
  • Qt5.12實(shí)戰(zhàn)之正則與QregExp使用

    1.普通字符匹配: ab+ : 匹配一個(gè)a和任意個(gè)b 如: ab abb abbbbbb c : 匹配一個(gè)c 如 : abcde 匹配內(nèi)容: c 匹配開始索引:2 匹配結(jié)束索引 3 bcd : 匹配字符串 bcd 如: abcde 匹配內(nèi)容是: bcd 匹配開始索引是:1 匹配結(jié)束索引是:4 2.轉(zhuǎn)換符匹配: :轉(zhuǎn)義字符匹配 如: r n t \\\\ ^ $ . 匹配的內(nèi)容分別是 回

    2024年02月06日
    瀏覽(21)
  • Ubuntu 下安裝Qt5.12.12無法輸入中文解決方法

    Ubuntu 下安裝Qt5.12.12無法輸入中文解決方法

    (1)VMware Workstation 15 Pro (2)Ubuntu 20.04 (3)Qt 5.12.12 64bits (4)Qt Creator 5.0.2 (5)已經(jīng)安裝了fcitx,google拼音和搜狗拼音。 安裝完Qt 5.12.12后,打開Qt Creator,發(fā)現(xiàn)無法輸入中文,并且點(diǎn)擊Ubuntu左上角的鍵盤,也無法切換中文輸入,Ubuntu已經(jīng)安裝了Fcitx。但是在其他的環(huán)境下是

    2024年02月11日
    瀏覽(23)
  • Ubuntu與致遠(yuǎn)ARM交叉編譯Qt5.12環(huán)境

    Ubuntu與致遠(yuǎn)ARM交叉編譯Qt5.12環(huán)境

    ????????ARM板現(xiàn)有環(huán)境配置(主要是對/etc/profile/編輯)較簡單,參考上一篇博客,板子上已經(jīng)部署了Qt5.15。 Ubuntu與國產(chǎn)致遠(yuǎn)ARM_3568交叉編譯Qt 此文檔只是為了記錄錯(cuò)誤的過程,下一往篇博客會(huì)直接介紹正確的配置。 https://blog.csdn.net/qq_35529025/article/details/129524412 ???????

    2024年02月22日
    瀏覽(19)
  • Qt5.12安裝教程+組件選擇MinGW+開源協(xié)議LGPL

    Qt5.12安裝教程+組件選擇MinGW+開源協(xié)議LGPL

    今天重裝了一下QT,發(fā)現(xiàn)以前忽略的點(diǎn),mark一下。 安裝QT或者平時(shí)新建項(xiàng)目的時(shí)候,常常碰到組件選擇界面,讓人頭疼。找到別人整理的文檔,為了自己以后搞清楚,摘自https://www.cnblogs.com/lixuejian/p/10903088.html 如下圖所示,安裝Qt時(shí)有選擇組件這一步,全部安裝未免太占磁盤控

    2024年02月15日
    瀏覽(17)
  • Qt5.12實(shí)戰(zhàn)之使用QLabel控件顯示圖像與動(dòng)畫

    Qt5.12實(shí)戰(zhàn)之使用QLabel控件顯示圖像與動(dòng)畫

    演示效果: 顯示圖像前先添加資源到qrc 直接復(fù)制到res目錄 然后添加已存在目錄 直接顯示圖像 加載圖像成功后顯示 顯示gif動(dòng)畫 顯示超鏈接

    2024年01月18日
    瀏覽(42)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包