激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C/C++ Qt QThread線程組件的具體使用

C/C++ Qt QThread線程組件的具體使用

2022-03-03 14:18lyshark C/C++

QThread庫是QT中提供的跨平臺多線程實現方案,本文詳細的介紹了Qt QThread線程組件的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

QThread庫是QT中提供的跨平臺多線程實現方案,使用時需要繼承QThread這個基類,并重寫實現內部的Run方法,由于該庫是基本庫,默認依賴于QtCore.dll這個基礎模塊,在使用時無需引入其他模塊.

實現簡單多線程

QThread庫提供了跨平臺的多線程管理方案,通常一個QThread對象管理一個線程,在使用是需要從QThread類繼承并重寫內部的Run方法,并在Run方法內部實現多線程代碼.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <QCoreApplication>
#include <iostream>
#include <QThread>
 
class MyThread: public QThread
{
 
protected:
    volatile bool m_to_stop;
 
protected:
    // 線程函數必須使用Run作為開始
    void run()
    {
        for(int x=0; !m_to_stop && (x <10); x++)
        {
            msleep(1000);
            std::cout << objectName().toStdString() << std::endl;
        }
    }
 
public:
    MyThread()
    {
        m_to_stop = false;
    }
 
    // 用于設置結束符號為真
    void stop()
    {
        m_to_stop = true;
    }
 
    // 輸出線程運行狀態
    void is_run()
    {
        std::cout << "Thread Running = " << isRunning() << std::endl;
    }
 
    // 輸出線程完成狀態(是否結束)
    void is_finish()
    {
        std::cout << "Thread Finished = " << isFinished() << std::endl;
    }
 
};
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    // 定義線程數組
    MyThread thread[10];
 
    // 設置線程對象名字
    for(int x=0;x<10;x++)
    {
        thread[x].setObjectName(QString("thread => %1").arg(x));
    }
 
    // 批量調用run執行
    for(int x=0;x<10;x++)
    {
        thread[x].start();
        thread[x].is_run();
        thread[x].isFinished();
    }
 
    // 批量調用stop關閉
    for(int x=0;x<10;x++)
    {
        thread[x].wait();
        thread[x].stop();
 
        thread[x].is_run();
        thread[x].is_finish();
    }
 
    return a.exec();
}

向線程中傳遞參數

線程在執行前可以通過調用MyThread中的自定義函數,并在函數內實現參數賦值,實現線程傳參操作.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <QCoreApplication>
#include <iostream>
#include <QThread>
 
class MyThread: public QThread
{
protected:
    int m_begin;
    int m_end;
    int m_result;
 
    void run()
    {
        m_result = m_begin + m_end;
    }
 
public:
    MyThread()
    {
        m_begin = 0;
        m_end = 0;
        m_result = 0;
    }
 
    // 設置參數給當前線程
    void set_value(int x,int y)
    {
        m_begin = x;
        m_end = y;
    }
 
    // 獲取當前線程名
    void get_object_name()
    {
        std::cout << "this thread name => " << objectName().toStdString() << std::endl;
    }
 
    // 獲取線程返回結果
    int result()
    {
        return m_result;
    }
};
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    MyThread thread[3];
 
    // 分別將不同的參數傳入到線程函數內
    for(int x=0; x<3; x++)
    {
        thread[x].set_value(1,2);
        thread[x].setObjectName(QString("thread -> %1").arg(x));
        thread[x].start();
    }
 
    // 等待所有線程執行結束
    for(int x=0; x<3; x++)
    {
        thread[x].get_object_name();
        thread[x].wait();
    }
 
    // 獲取線程返回值并相加
    int result = thread[0].result() + thread[1].result() + thread[2].result();
    std::cout << "sum => " << result << std::endl;
 
    return a.exec();
}

QMutex 互斥同步線程鎖

QMutex類是基于互斥量的線程同步鎖,該鎖lock()鎖定與unlock()解鎖必須配對使用,線程鎖保證線程間的互斥,利用線程鎖能夠保證臨界資源的安全性.

  • 線程鎖解決的問題: 多個線程同時操作同一個全局變量,為了防止資源的無序覆蓋現象,從而需要增加鎖,來實現多線程搶占資源時可以有序執行.
  • 臨界資源(Critical Resource): 每次只允許一個線程進行訪問 (讀/寫)的資源.
  • 線程間的互斥(競爭): 多個線程在同一時刻都需要訪問臨界資源.
  • 一般性原則: 每一個臨界資源都需要一個線程鎖進行保護.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <QCoreApplication>
#include <iostream>
#include <QThread>
#include <QMutex>
 
static QMutex g_mutex;      // 線程鎖
static QString g_store;     // 定義全局變量
 
class Producer : public QThread
{
protected:
    void run()
    {
        int count = 0;
 
        while(true)
        {
            // 加鎖
            g_mutex.lock();
 
            g_store.append(QString::number((count++) % 10));
            std::cout << "Producer -> "<< g_store.toStdString() << std::endl;
 
            // 釋放鎖
            g_mutex.unlock();
            msleep(900);
        }
    }
};
 
class Customer : public QThread
{
protected:
    void run()
    {
        while( true )
        {
            g_mutex.lock();
            if( g_store != "" )
            {
                g_store.remove(0, 1);
                std::cout << "Curstomer -> "<< g_store.toStdString() << std::endl;
            }
 
            g_mutex.unlock();
            msleep(1000);
        }
    }
};
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    Producer p;
    Customer c;
 
    p.setObjectName("producer");
    c.setObjectName("curstomer");
 
    p.start();
    c.start();
 
    return a.exec();
}

QMutexLocker是在QMutex基礎上簡化版的線程鎖,QMutexLocker會保護加鎖區域,并自動實現互斥量的鎖定和解鎖操作,可以將其理解為是智能版的QMutex鎖,該鎖只需要在上方代碼中稍加修改即可.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <QMutex>
#include <QMutexLocker>
 
static QMutex g_mutex;      // 線程鎖
static QString g_store;     // 定義全局變量
 
class Producer : public QThread
{
protected:
    void run()
    {
        int count = 0;
 
        while(true)
        {
            // 增加智能線程鎖
            QMutexLocker Locker(&g_mutex);
 
            g_store.append(QString::number((count++) % 10));
            std::cout << "Producer -> "<< g_store.toStdString() << std::endl;
 
            msleep(900);
        }
    }
};

互斥鎖存在一個問題,每次只能有一個線程獲得互斥量的權限,如果在程序中有多個線程來同時讀取某個變量,那么使用互斥量必須排隊,效率上會大打折扣,基于QReadWriteLock讀寫模式進行代碼段鎖定,即可解決互斥鎖存在的問題.

QReadWriteLock 讀寫同步線程鎖

該鎖允許用戶以同步讀lockForRead()或同步寫lockForWrite()兩種方式實現保護資源,但只要有一個線程在以寫的方式操作資源,其他線程也會等待寫入操作結束后才可繼續讀資源.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <QCoreApplication>
#include <iostream>
#include <QThread>
#include <QMutex>
#include <QReadWriteLock>
 
static QReadWriteLock g_mutex;      // 線程鎖
static QString g_store;             // 定義全局變量
 
class Producer : public QThread
{
protected:
    void run()
    {
        int count = 0;
 
        while(true)
        {
            // 以寫入方式鎖定資源
            g_mutex.lockForWrite();
 
            g_store.append(QString::number((count++) % 10));
 
            // 寫入后解鎖資源
            g_mutex.unlock();
 
            msleep(900);
        }
    }
};
 
class Customer : public QThread
{
protected:
    void run()
    {
        while( true )
        {
            // 以讀取方式寫入資源
            g_mutex.lockForRead();
            if( g_store != "" )
            {
                std::cout << "Curstomer -> "<< g_store.toStdString() << std::endl;
            }
 
            // 讀取到后解鎖資源
            g_mutex.unlock();
            msleep(1000);
        }
    }
};
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    Producer p1,p2;
    Customer c1,c2;
 
    p1.setObjectName("producer 1");
    p2.setObjectName("producer 2");
 
    c1.setObjectName("curstomer 1");
    c2.setObjectName("curstomer 2");
 
    p1.start();
    p2.start();
 
    c1.start();
    c2.start();
 
    return a.exec();
}

QSemaphore 基于信號線程鎖

信號量是特殊的線程鎖,信號量允許N個線程同時訪問臨界資源,通過acquire()獲取到指定資源,release()釋放指定資源.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <QCoreApplication>
#include <iostream>
#include <QThread>
#include <QSemaphore>
 
const int SIZE = 5;
unsigned char g_buff[SIZE] = {0};
 
QSemaphore g_sem_free(SIZE); // 5個可生產資源
QSemaphore g_sem_used(0);    // 0個可消費資源
 
// 生產者生產產品
class Producer : public QThread
{
protected:
    void run()
    {
        while( true )
        {
            int value = qrand() % 256;
 
            // 若無法獲得可生產資源,阻塞在這里
            g_sem_free.acquire();
 
            for(int i=0; i<SIZE; i++)
            {
                if( !g_buff[i] )
                {
                    g_buff[i] = value;
                    std::cout << objectName().toStdString() << " --> " << value << std::endl;
                    break;
                }
            }
 
            // 可消費資源數+1
            g_sem_used.release();
 
            sleep(2);
        }
    }
};
 
// 消費者消費產品
class Customer : public QThread
{
protected:
    void run()
    {
        while( true )
        {
            // 若無法獲得可消費資源,阻塞在這里
            g_sem_used.acquire();
 
            for(int i=0; i<SIZE; i++)
            {
                if( g_buff[i] )
                {
                    int value = g_buff[i];
 
                    g_buff[i] = 0;
                    std::cout << objectName().toStdString() << " --> " << value << std::endl;
                    break;
                }
            }
 
            // 可生產資源數+1
            g_sem_free.release();
 
            sleep(1);
        }
    }
};
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    Producer p1;
    Customer c1;
 
    p1.setObjectName("producer");
    c1.setObjectName("curstomer");
 
    p1.start();
    c1.start();
 
    return a.exec();
}

到此這篇關于C/C++ Qt QThread線程組件的具體使用的文章就介紹到這了,更多相關Qt QThread線程使用內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/LyShark/p/15555343.html

延伸 · 閱讀

精彩推薦
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
主站蜘蛛池模板: 国产肥熟| 国产精品视频亚洲 | 最污网站 | 中文字幕国产欧美 | 青青草成人av | 亚洲第一视频在线 | 国产精品美女久久久免费 | 国产精品视频免费在线观看 | 蜜桃久久一区二区三区 | 国产一级在线免费观看 | 黄色片网站在线免费观看 | 日本成人在线免费 | 黄色国产在线观看 | 神马顶级推理片免费看 | 色网在线视频 | 成人wxx视频免费 | 国产午夜免费不卡精品理论片 | 电影一级毛片 | 国产一级在线观看视频 | 成人片在线播放 | 成人综合一区二区 | 国内精品久久久久久影视8 国产一区二区成人在线 | 8x成人在线电影 | 9999免费视频| 一级免费a | 羞羞视频免费视频欧美 | 天天鲁在线视频免费观看 | 亚洲欧美日韩精品久久 | 在线小视频国产 | 黄色欧美精品 | 色诱亚洲精品久久久久久 | 精品一区在线视频 | xnxx 日本19| 99精美视频| 成人黄色免费视频 | 在线成人一区 | 污污的视频在线观看 | 黄色片网页 | 日韩在线视频免费观看 | 成人午夜免费网站 | 国产精品久久久久久久久粉嫩 |