久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Qt線程詳解

 ylsnData 2018-07-06
回顧Qt之線程(QThread),里面講解了如何使用線程,,但還有很多人留言沒有看明白,,那么今天我們來一起瞅瞅關(guān)于QThread管理線程的那些事兒。,。,。

一、線程管理

1,、線程啟動(dòng)

void?start(Priority priority = InheritPriority)

調(diào)用后會執(zhí)行run()函數(shù),,但在run()函數(shù)執(zhí)行前會發(fā)射信號started(),操作系統(tǒng)將根據(jù)優(yōu)先級參數(shù)調(diào)度線程,。如果線程已經(jīng)在運(yùn)行,,那么這個(gè)函數(shù)什么也不做。優(yōu)先級參數(shù)的效果取決于操作系統(tǒng)的調(diào)度策略,。特別是那些不支持線程優(yōu)先級的系統(tǒng)優(yōu)先級將會被忽略(例如在Linux中,,更多細(xì)節(jié)請參考http://linux./man/2/sched_setscheduler)。


2,、線程執(zhí)行

int?exec()

進(jìn)入事件循環(huán)并等待直到調(diào)用exit(),,返回值是通過調(diào)用exit()來獲得,如果調(diào)用成功則范圍0,。

virtual void?run();

線程的起點(diǎn),,在調(diào)用start()之后,新創(chuàng)建的線程就會調(diào)用這個(gè)函數(shù),,默認(rèn)實(shí)現(xiàn)調(diào)用exec(),大多數(shù)需要重新實(shí)現(xiàn)這個(gè)功能,,便于管理自己的線程,。該方法返回時(shí),該線程的執(zhí)行將結(jié)束,。


3,、線程退出

void?quit()

告訴線程事件循環(huán)退出,返回0表示成功,,相當(dāng)于調(diào)用了QThread::exit(0),。

void?exit(int returnCode = 0)

告訴線程事件循環(huán)退出。

調(diào)用這個(gè)函數(shù)后,,線程離開事件循環(huán)后返回,,QEventLoop::exec()返回returnCode

按照慣例0表示成功,任何非0值表示失敗,。

void?terminate()

終止線程,,線程可能會立即被終止也可能不會,這取決于操作系統(tǒng)的調(diào)度策略,,使用terminate()之后再使用QThread::wait()確保萬無一失,。

當(dāng)線程被終止后,所有等待中的線程將會被喚醒,。

警告:此功能比較危險(xiǎn),,不鼓勵(lì)使用,。線程可以在代碼執(zhí)行的任何點(diǎn)被終止,。線程可能在更新數(shù)據(jù)時(shí)被終止,從而沒有機(jī)會來清理自己,,解鎖等等,。,。??傊?,只有在絕對必要時(shí)使用此功能。

建議:一般情況下,,都在run函數(shù)里面設(shè)置一個(gè)標(biāo)識符,,可以控制循環(huán)停止。然后才調(diào)用quit函數(shù),,退出線程,。


4線程等待

void?msleep(unsigned long msecs)

強(qiáng)制當(dāng)前線程睡眠msecs毫秒

void?sleep(unsigned long secs)

強(qiáng)制當(dāng)前線程睡眠secs

void?usleep(unsigned long usecs)

強(qiáng)制當(dāng)前線程睡眠usecs

bool wait(unsigned long time = ULONG_MAX);

線程將會被阻塞,,等待time毫秒,。和sleep不同的是,如果線程退出,,wait會返回,。


5線程狀態(tài)

????bool?isFinished()?const ???

????線程是否結(jié)束

????bool?isRunning() const ???
????線程是否正在運(yùn)行

6,、線程優(yōu)先級

????void?setPriority(Priority priority)
????這個(gè)函數(shù)設(shè)置正在運(yùn)行線程的優(yōu)先級,。如果線程沒有運(yùn)行,此功能不執(zhí)行任何操作并立即返回,。使用的start()來啟動(dòng)一個(gè)線程具有特定的優(yōu)先級,。
????優(yōu)先級參數(shù)可以是QThread::Priority枚舉除InheritPriortyd的任何值。
????Priority?priority() const
????下面來看下優(yōu)先級中的各個(gè)枚舉值:

Constant

Value

Description

QThread::IdlePriority

0

沒有其它線程運(yùn)行時(shí)才調(diào)度.

QThread::LowestPriority

1

比LowPriority調(diào)度頻率低.

QThread::LowPriority

2

比NormalPriority調(diào)度頻率低.

QThread::NormalPriority

3

操作系統(tǒng)默認(rèn)的默認(rèn)優(yōu)先級.

QThread::HighPriority

4

比NormalPriority調(diào)度頻繁.

QThread::HighestPriority

5

比HighPriority調(diào)度頻繁.

QThread::TimeCriticalPriority

6

盡可能頻繁的調(diào)度.

QThread::InheritPriority

7

使用和創(chuàng)建線程同樣的優(yōu)先級. 這是默認(rèn)值.


二,、主線程,、次線程

Qt之線程(QThread)一節(jié)中我介紹了QThread 的兩種使用方法:

1,、子類化 QThread(不使用事件循環(huán))

這是官方手冊,、例子以及相關(guān)書籍中都介紹的一種常用的方法,。

a. 子類化 QThread

b. 重載 run 函數(shù),run函數(shù)內(nèi)有一個(gè)while或for的死循環(huán)(模擬耗時(shí)操作)

c. 設(shè)置一個(gè)標(biāo)記為來控制死循環(huán)的退出,。


2,、子類化?QObject

a. 子類化?QObject

b.?定義槽函數(shù)

c.?將該子類的對象moveToThread到新線程中


run 對于線程的作用相當(dāng)于main函數(shù)對于應(yīng)用程序。它是線程的入口,,run的開始和結(jié)束意味著線程的開始和結(jié)束,。

采用這兩種做法,毫無疑問都會在次線程中運(yùn)行(這里說的是,,run中的邏輯以及子類化QObject后連接通過moveToThread然后連接到QThread的started()信號的槽函數(shù),,這個(gè)下面會詳細(xì)講解)。

那么,,線程中的槽函數(shù)是怎么運(yùn)行的呢,?

說到信號與槽,大家應(yīng)該再熟悉不過了,,包括我,,特別喜歡使用自定義信號與槽,感覺用起來特方便,、特棒,。。,。

經(jīng)常使用,,你能否100%的使用正確?你了解它的高級用法嗎,?

1,、你是否在多次connect,還發(fā)現(xiàn)不了為什么槽函數(shù)會執(zhí)行那N多次,。

2,、你是否了解disconnect

3、你是否了解connect中的第五個(gè)參數(shù)?Qt::ConnectionType

關(guān)于connect,、disconnect信號、槽的使用可參考:Qt之信號與槽,。既然談到線程這里需要重點(diǎn)說下Qt::ConnectionType(信號與槽的傳遞方式)

Constant

Value

Description

Qt::AutoConnection

0

自動(dòng)連接:(默認(rèn)值)如果信號在接收者所依附的線程內(nèi)發(fā)射,,則等同于直接連接。如果發(fā)射信號的線程和接受者所依附的線程不同,,則等同于隊(duì)列連接,。

Qt::DirectConnection

1

直接連接:當(dāng)信號發(fā)射時(shí),,槽函數(shù)將直接被調(diào)用。無論槽函數(shù)所屬對象在哪個(gè)線程,,槽函數(shù)都在發(fā)射信號的線程內(nèi)執(zhí)行,。

Qt::QueuedConnection

2

隊(duì)列連接:當(dāng)控制權(quán)回到接受者所依附線程的事件循環(huán)時(shí),槽函數(shù)被調(diào)用,。槽函數(shù)在接收者所依附線程執(zhí)行,。也就是說:這種方式既可以在線程內(nèi)傳遞消息,也可以跨線程傳遞消息

Qt::BlockingQueuedConnection

3

與Qt::QueuedConnection類似,,但是會阻塞等到關(guān)聯(lián)的slot都被執(zhí)行,。這里出現(xiàn)了阻塞這個(gè)詞,說明它是專門用來多線程間傳遞消息的,。


舉例:

MyObject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include 

class MyObject : public QObject
{
    Q_OBJECT

public:
    explicit MyObject(QObject *parent = 0);

public slots:
    void start();
};

#endif // MYOBJECT_H
MyObject.cpp
#include "MyObject.h"
#include 
#include 

MyObject::MyObject(QObject *parent)
    : QObject(parent)
{

}

void MyObject::start()
{
    qDebug() << QString("my object thread id:") << QThread::currentThreadId();
}
main.cpp
#include "MyObject.h"
#include 
#include 
#include 

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

    qDebug() << QString("main thread id:") << QThread::currentThreadId();

    MyObject object;
    QThread thread;
    object.moveToThread(&thread);
    QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()));
    thread.start();

    return a.exec();
}?
查看運(yùn)行結(jié)果:

??"main thread id:" 0xf08

??"my object thread id:" 0x216c

????顯然主線程與槽函數(shù)的線程是不同的(你可以多次嘗試,,屢試不爽。,。,。),因?yàn)?/span>moveToThread后MyObject所在的線程為QThread,,繼上面介紹的thread.start()執(zhí)行后首先會發(fā)射started()信號,,也就是說started()信號發(fā)射是在線程中進(jìn)行的,所以無論采取Qt::AutoConnection,、Qt::DirectConnection,、Qt::QueuedConnection哪種連接方式,主線程與槽函數(shù)的線程都是不同的,。

?

1,、修改代碼如下:

    MyObject object;
    QThread thread;
    //object.moveToThread(&thread);
    QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::DirectConnection);
    thread.start();
查看運(yùn)行結(jié)果:

??"main thread id:" 0x2688

??"my object thread id:" 0x2110?

????顯然主線程與槽函數(shù)的線程是不同的,MyObject所依附的線程為主線程(因?yàn)樽⑨尩袅?/span>moveToThread,,繼上面介紹的Qt::DirectConnection無論槽函數(shù)所屬對象在哪個(gè)線程,,槽函數(shù)都在發(fā)射信號的線程內(nèi)執(zhí)行)。也就是說started()信號發(fā)射是在次線程中進(jìn)行的,,槽函數(shù)也是在次線程中進(jìn)行的,,所以主線程與槽函數(shù)的線程是不同的。


2,、修改代碼如下:

    MyObject object;
    QThread thread;
    //object.moveToThread(&thread);
    QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::QueuedConnection);
    thread.start();

查看運(yùn)行結(jié)果:

??"main thread id:" 0x24ec

??"my object thread id:" 0x24ec?

????顯然主線程與槽函數(shù)的線程是相同的,,繼上面介紹的Qt::QueuedConnection槽函數(shù)在接收者所依附線程執(zhí)行)。也就是說started()信號發(fā)射是在次線程中進(jìn)行的,,但MyObject所依附的線程為主線程(因?yàn)樽⑨尩袅?/span>moveToThread),,所以主線程與槽函數(shù)的線程必然是相同的。


3,、修改代碼如下:

    MyObject object;
    QThread thread;
    //object.moveToThread(&thread);
    QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::AutoConnection);
    thread.start();
查看運(yùn)行結(jié)果:

??"main thread id:" 0x2700

??"my object thread id:" 0x2700?

????顯然主線程與槽函數(shù)的線程是相同的,,MyObject所依附的線程為主線程(因?yàn)樽⑨尩袅?/span>moveToThread,,繼上面介紹的Qt::AutoConnection如果信號在接收者所依附的線程內(nèi)發(fā)射,則等同于直接連接,。如果發(fā)射信號的線程和接受者所依附的線程不同,,則等同于隊(duì)列連接。),。因?yàn)閟tarted()信號和MyObject依附的線程不同,,所以結(jié)果和Qt::QueuedConnection對應(yīng)的相同,所以主線程與槽函數(shù)的線程是相同的,。


????基本就介紹到這里,,QThread使用和上面的大同小異,run里面執(zhí)行的代碼都是在次線程中,,如果是QThead的槽函數(shù),,那么結(jié)論同上!



注:
????技術(shù)在于交流,、溝通,,轉(zhuǎn)載請注明出處并保持作品的完整性。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多