青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-1  評論-10  文章-0  trackbacks-0
  置頂隨筆

第一回 Signal和Slot是同步的還是異步的?

  我們知道Qt以他的signal和slot機制獨步天下。但大家在用的時候有沒有注意過,signal和slot之間是異步的,還是同步的呢?為此我問過不少使用Qt的道友。有人說是同步的,有人說是異步的,也有人說要看當時你的人品。:( #$%^&*

  為此貧道,特別做了以下幾個測試:

     First,在main()主函數里,設置兩個基于QObject為父類的對象a和b,a觸發signal,b接受signal。請看具體案例:

    

 1 class MyTestA : public QObject
2 {
3 Q_OBJECT
4 public:
5 void emitSignal()
6 {
7 signalMyTestA();
8 }
9
10 public slots:
11 void slotMyTestA()
12 {
13 qDebug()<<"slotMyTestA is called.";
14 }
15 signals:
16 void signalMyTestA();
17 };
18
19 class MyTestB : public QObject
20 {
21 Q_OBJECT
22 public slots:
23 void slotMyTestB()
24 {
25 qDebug()<<"slotMyTestB is called.";
26 }
27 signals:
28 void signalMyTestB();
29 };
30
31 int main(int argc, char *argv[])
32 {
33 QApplication app(argc, argv);
34
35 MyTestA a;
36 MyTestB b;
37 QObject::connect(&a,SIGNAL(signalMyTestA()),&b,SLOT(slotMyTestB()));
38
39 a.emitSignal();
40
41 return app.exec();
42 }

在slotMyTestB的函數里打個斷點,看一下調用堆棧(call stack)。

是同步調用的,某些道友開始拈胡微笑,實踐出真知啊。

此時只見東方黑云滾滾,電閃雷鳴,又有道友開始度劫了。突然一度劫道友橫眉冷對,拿起拂塵刷刷的改寫了上面的代碼。只見此道友把a對象挪到了一個新線程中(MyTestC創建的),而b對象仍然在主線程中。然后a對象觸發信號。

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        signalMyTestA();
    }
public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA();
};
class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB()
    {
        qDebug()<<"slotMyTestB is called.";
    }
signals:
    void signalMyTestB();
};
extern MyTestB *g_pMyTestB;
class MyTestC : public QThread
{
    Q_OBJECT
public:
    void run()
    {
        MyTestA a;
        connect(&a,SIGNAL(signalMyTestA()),g_pMyTestB,SLOT(slotMyTestB()));
        a.emitSignal();
        exec();
    }
public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();
};
class MyTest : public QDialog
{
    Q_OBJECT
public:
    MyTest(QWidget *parent = 0, Qt::WFlags flags = 0);
    ~MyTest();
private:
    Ui::MyTestClass ui;
};
////////////////////////////////////////////////
MyTestB *g_pMyTestB = NULL;
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MyTestB b;
    g_pMyTestB = &b;
    MyTestC c;
    c.start();
    return app.exec();
}

說時遲,那時快。在一道紫雷劈下之際,按下了F5。只見,此時的調用堆棧顯示,

奇跡出現了,居然變成異步調用了。只見東方天空萬道金光射下,在陣陣仙樂聲中,傳來朗朗之聲:"貧道塵事已了,再無牽掛"。

難道Qt真的是靠人品的,或者Qt莫不是也是修仙道友,不日也將飛升。

在吾等眾人膜拜加疑惑之時,只見飛升前輩,留下一條偈語。內事不決問百度,外事不決問谷歌。

吾等眾人立刻搜尋,恍然大物。

原來signal和slot是異步調用還是同步調用,取決于對connect的設定。其實connect還有一個參數(Qt::ConnectionType),是它決定了是同步還是異步。以下是ConnectionType的定義

只不過,平常它有一個默認值Qt::AutoConnection,我們忽略了它。這時有道友問道,為何在AutoConnection模式下,有時是同步,有時是異步,莫非Auto就是人品代名詞。

非也,其實Auto是這樣規定的,

當sender和receiver在同一線程時,就是同步模式,而在不同線程時,則是異步模式。

眾人皆曰善。

就在眾人彈冠相慶之時,突然一道類似眼鏡發出的寒光閃過,一個黑影漸漸清晰了起來。

他居然就是..................

青春永駐,十二年如一日的柯南君,他招牌式的磁性聲音給眾道友一晴天霹靂,“諸位以為這就是全部的真相嗎?”

接著他刷刷的又改寫了代碼,在主線程中生成a,b兩個對象,而a對象在新線程(MyTestC創建的)中觸發信號。

 

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        signalMyTestA();
    }
public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA();
};
class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB()
    {
        qDebug()<<"slotMyTestB is called.";
    }
signals:
    void signalMyTestB();
};
extern MyTestB *g_pMyTestB;
extern MyTestA *g_pMyTestA;
class MyTestC : public QThread
{
    Q_OBJECT
public:
    void run()
    {
        g_pMyTestA->emitSignal();
        exec();
    }
public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();
};
/////////////////////////////////////////////
MyTestB *g_pMyTestB = NULL;
MyTestA *g_pMyTestA = NULL;
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MyTestA a;
    g_pMyTestA = &a;
    MyTestB b;
    g_pMyTestB = &b;
    QObject::connect(&a,SIGNAL(signalMyTestA()),&b,SLOT(slotMyTestB()));
    MyTestC c;
    c.start();
    return app.exec();
}

 

在眾人疑惑的眼光中,此君淡定的按下了F5。只見調用堆棧(call stack)顯示

眾人皆驚呼,“Impossible”。a和b明明是屬于一個線程的,為何會異步調用。此時我們熟悉的語錄,又在耳邊回響,是"我相信真相只有一個!!!"這句話嗎?No,只見柯南君,優雅地揮了揮手指,"Nothing impossible",從口中緩緩滑出。

。眾人皆撲街,“有屁快放”。

此時柯南君緩緩從口袋中,摸出一張紙,拋向空中,然后轉身離去。只見隨風飄落的紙面上面摘錄了這么一段Qt源代碼,在Auto模式下,如果要同步調用,不僅要求sender和receiver是同一線程,而且sender觸發的時候,所在的線程也要和receiver一致。

 // determine if this connection should be sent immediately or
            // put into the event queue
            if ((c->connectionType == Qt::AutoConnection
                 && (currentThreadData != sender->d_func()->threadData
                     || receiver->d_func()->threadData != sender->d_func()->threadData))
                || (c->connectionType == Qt::QueuedConnection)) {
                queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
                continue;
            } else if (c->connectionType == Qt::BlockingQueuedConnection) {
                blocking_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
                continue;
            }

摘自qobject.cpp

z眾人皆驚,原來在Auto模式下,如果sender的觸發時所處的線程和receiver不同,也會是異步調用。此時道友齊聲向柯南喊道“這是全部的真相了嗎”?柯南轉過頭來笑而不語,漸漸又消失在黑暗中。“有多少無恥可以重來”漂上了眾人的心頭。望著遠處的雨后陽光,一個大大的問號也出現在眾人頭頂,"Qt你到底有多無恥???"。眾人又陷入了沉思。

欲知后事如何,請聽下回分解。

 

此篇已在CNBLOG同時發布

 

 

 

 

 

 




posted @ 2011-08-26 10:41 櫻桃小錘子 閱讀(12988) | 評論 (10)編輯 收藏
  2011年8月26日

第一回 Signal和Slot是同步的還是異步的?

  我們知道Qt以他的signal和slot機制獨步天下。但大家在用的時候有沒有注意過,signal和slot之間是異步的,還是同步的呢?為此我問過不少使用Qt的道友。有人說是同步的,有人說是異步的,也有人說要看當時你的人品。:( #$%^&*

  為此貧道,特別做了以下幾個測試:

     First,在main()主函數里,設置兩個基于QObject為父類的對象a和b,a觸發signal,b接受signal。請看具體案例:

    

 1 class MyTestA : public QObject
2 {
3 Q_OBJECT
4 public:
5 void emitSignal()
6 {
7 signalMyTestA();
8 }
9
10 public slots:
11 void slotMyTestA()
12 {
13 qDebug()<<"slotMyTestA is called.";
14 }
15 signals:
16 void signalMyTestA();
17 };
18
19 class MyTestB : public QObject
20 {
21 Q_OBJECT
22 public slots:
23 void slotMyTestB()
24 {
25 qDebug()<<"slotMyTestB is called.";
26 }
27 signals:
28 void signalMyTestB();
29 };
30
31 int main(int argc, char *argv[])
32 {
33 QApplication app(argc, argv);
34
35 MyTestA a;
36 MyTestB b;
37 QObject::connect(&a,SIGNAL(signalMyTestA()),&b,SLOT(slotMyTestB()));
38
39 a.emitSignal();
40
41 return app.exec();
42 }

在slotMyTestB的函數里打個斷點,看一下調用堆棧(call stack)。

是同步調用的,某些道友開始拈胡微笑,實踐出真知啊。

此時只見東方黑云滾滾,電閃雷鳴,又有道友開始度劫了。突然一度劫道友橫眉冷對,拿起拂塵刷刷的改寫了上面的代碼。只見此道友把a對象挪到了一個新線程中(MyTestC創建的),而b對象仍然在主線程中。然后a對象觸發信號。

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        signalMyTestA();
    }
public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA();
};
class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB()
    {
        qDebug()<<"slotMyTestB is called.";
    }
signals:
    void signalMyTestB();
};
extern MyTestB *g_pMyTestB;
class MyTestC : public QThread
{
    Q_OBJECT
public:
    void run()
    {
        MyTestA a;
        connect(&a,SIGNAL(signalMyTestA()),g_pMyTestB,SLOT(slotMyTestB()));
        a.emitSignal();
        exec();
    }
public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();
};
class MyTest : public QDialog
{
    Q_OBJECT
public:
    MyTest(QWidget *parent = 0, Qt::WFlags flags = 0);
    ~MyTest();
private:
    Ui::MyTestClass ui;
};
////////////////////////////////////////////////
MyTestB *g_pMyTestB = NULL;
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MyTestB b;
    g_pMyTestB = &b;
    MyTestC c;
    c.start();
    return app.exec();
}

說時遲,那時快。在一道紫雷劈下之際,按下了F5。只見,此時的調用堆棧顯示,

奇跡出現了,居然變成異步調用了。只見東方天空萬道金光射下,在陣陣仙樂聲中,傳來朗朗之聲:"貧道塵事已了,再無牽掛"。

難道Qt真的是靠人品的,或者Qt莫不是也是修仙道友,不日也將飛升。

在吾等眾人膜拜加疑惑之時,只見飛升前輩,留下一條偈語。內事不決問百度,外事不決問谷歌。

吾等眾人立刻搜尋,恍然大物。

原來signal和slot是異步調用還是同步調用,取決于對connect的設定。其實connect還有一個參數(Qt::ConnectionType),是它決定了是同步還是異步。以下是ConnectionType的定義

只不過,平常它有一個默認值Qt::AutoConnection,我們忽略了它。這時有道友問道,為何在AutoConnection模式下,有時是同步,有時是異步,莫非Auto就是人品代名詞。

非也,其實Auto是這樣規定的,

當sender和receiver在同一線程時,就是同步模式,而在不同線程時,則是異步模式。

眾人皆曰善。

就在眾人彈冠相慶之時,突然一道類似眼鏡發出的寒光閃過,一個黑影漸漸清晰了起來。

他居然就是..................

青春永駐,十二年如一日的柯南君,他招牌式的磁性聲音給眾道友一晴天霹靂,“諸位以為這就是全部的真相嗎?”

接著他刷刷的又改寫了代碼,在主線程中生成a,b兩個對象,而a對象在新線程(MyTestC創建的)中觸發信號。

 

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        signalMyTestA();
    }
public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA();
};
class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB()
    {
        qDebug()<<"slotMyTestB is called.";
    }
signals:
    void signalMyTestB();
};
extern MyTestB *g_pMyTestB;
extern MyTestA *g_pMyTestA;
class MyTestC : public QThread
{
    Q_OBJECT
public:
    void run()
    {
        g_pMyTestA->emitSignal();
        exec();
    }
public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();
};
/////////////////////////////////////////////
MyTestB *g_pMyTestB = NULL;
MyTestA *g_pMyTestA = NULL;
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MyTestA a;
    g_pMyTestA = &a;
    MyTestB b;
    g_pMyTestB = &b;
    QObject::connect(&a,SIGNAL(signalMyTestA()),&b,SLOT(slotMyTestB()));
    MyTestC c;
    c.start();
    return app.exec();
}

 

在眾人疑惑的眼光中,此君淡定的按下了F5。只見調用堆棧(call stack)顯示

眾人皆驚呼,“Impossible”。a和b明明是屬于一個線程的,為何會異步調用。此時我們熟悉的語錄,又在耳邊回響,是"我相信真相只有一個!!!"這句話嗎?No,只見柯南君,優雅地揮了揮手指,"Nothing impossible",從口中緩緩滑出。

。眾人皆撲街,“有屁快放”。

此時柯南君緩緩從口袋中,摸出一張紙,拋向空中,然后轉身離去。只見隨風飄落的紙面上面摘錄了這么一段Qt源代碼,在Auto模式下,如果要同步調用,不僅要求sender和receiver是同一線程,而且sender觸發的時候,所在的線程也要和receiver一致。

 // determine if this connection should be sent immediately or
            // put into the event queue
            if ((c->connectionType == Qt::AutoConnection
                 && (currentThreadData != sender->d_func()->threadData
                     || receiver->d_func()->threadData != sender->d_func()->threadData))
                || (c->connectionType == Qt::QueuedConnection)) {
                queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
                continue;
            } else if (c->connectionType == Qt::BlockingQueuedConnection) {
                blocking_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
                continue;
            }

摘自qobject.cpp

z眾人皆驚,原來在Auto模式下,如果sender的觸發時所處的線程和receiver不同,也會是異步調用。此時道友齊聲向柯南喊道“這是全部的真相了嗎”?柯南轉過頭來笑而不語,漸漸又消失在黑暗中。“有多少無恥可以重來”漂上了眾人的心頭。望著遠處的雨后陽光,一個大大的問號也出現在眾人頭頂,"Qt你到底有多無恥???"。眾人又陷入了沉思。

欲知后事如何,請聽下回分解。

 

此篇已在CNBLOG同時發布

 

 

 

 

 

 




posted @ 2011-08-26 10:41 櫻桃小錘子 閱讀(12988) | 評論 (10)編輯 收藏
僅列出標題  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一区二区三区喷汁尤物| 亚洲精品日韩综合观看成人91| 亚洲影院一区| 国产欧美日韩在线播放| 久久国产乱子精品免费女| 久久不射电影网| 亚洲国产乱码最新视频| 亚洲伦理在线免费看| 国产精品国产三级国产普通话蜜臀 | 久久亚洲影院| 老司机精品久久| 一区二区三区你懂的| 亚洲午夜国产成人av电影男同| 国产亚洲电影| 欧美激情视频在线播放| 欧美日韩在线电影| 久久青草久久| 欧美日产国产成人免费图片| 欧美怡红院视频一区二区三区| 久久久精品日韩欧美| 亚洲精品偷拍| 亚洲一区在线观看视频 | 国产精品乱码一区二三区小蝌蚪| 久久久久国产精品一区三寸| 欧美成人免费大片| 欧美一区二区三区视频在线观看| 久久综合图片| 久久av一区二区三区漫画| 欧美顶级少妇做爰| 久久精品综合| 国产精品进线69影院| 欧美成年人视频网站| 国产精品揄拍500视频| 亚洲国产精品传媒在线观看 | 亚洲精品影视| 欧美精品成人在线| 香蕉久久精品日日躁夜夜躁| 久久综合给合| 久久久久九九九| 国产精品老牛| 亚洲日本va午夜在线电影| 国内精品久久久久影院薰衣草| 日韩天堂在线观看| 亚洲国产精品黑人久久久| 亚洲欧美日本日韩| 亚洲一区二区动漫| 欧美精品尤物在线| 免费看的黄色欧美网站| 国产一级一区二区| 这里只有精品在线播放| 一本久久青青| 欧美久久久久久久| 亚洲第一综合天堂另类专| 激情懂色av一区av二区av| 亚洲欧美另类国产| 欧美亚洲视频一区二区| 国产精品久久9| 国产精品99久久久久久久久| 亚洲视频在线观看视频| 欧美日韩高清一区| 亚洲人成网站精品片在线观看 | 欧美aaa级| 欧美va日韩va| 亚洲国产精品黑人久久久 | 一本综合久久| 亚洲愉拍自拍另类高清精品| 国产精品va在线播放我和闺蜜| 日韩视频亚洲视频| 亚洲你懂的在线视频| 国产精品婷婷午夜在线观看| 亚洲制服丝袜在线| 久久久青草婷婷精品综合日韩| 国内成人精品视频| 蜜臀a∨国产成人精品| 亚洲国产小视频| 一区二区三区四区在线| 欧美视频中文字幕在线| 亚洲午夜精品在线| 久久婷婷国产综合尤物精品| 伊大人香蕉综合8在线视| 免费不卡亚洲欧美| 91久久在线| 欧美在线精品免播放器视频| 红桃视频欧美| 欧美成人午夜免费视在线看片| 亚洲精品欧洲| 欧美在现视频| 亚洲欧洲日本国产| 国产精品国产自产拍高清av| 欧美一区二区福利在线| 欧美国产丝袜视频| 亚洲女人av| ●精品国产综合乱码久久久久| 欧美精品在线一区二区| 午夜精品久久| 亚洲精品一区二区三区不| 性欧美精品高清| 亚洲国产一区二区a毛片| 亚洲午夜精品视频| 亚洲精品视频在线观看网站| 国产精品青草综合久久久久99| 久久久天天操| 9人人澡人人爽人人精品| 久久久夜色精品亚洲| 一区二区三区高清不卡| 黄色另类av| 国产精品久久久久久亚洲调教| 久久男人资源视频| 亚洲女同性videos| 亚洲精品国产精品久久清纯直播 | 在线综合视频| 亚洲国产成人久久| 国产日韩欧美亚洲| 欧美午夜性色大片在线观看| 久久人人超碰| 欧美一区二区三区电影在线观看| 91久久精品美女高潮| 久久综合久久综合久久综合| 性欧美18~19sex高清播放| 亚洲国产日日夜夜| 狠狠色狠色综合曰曰| 国产精品日日摸夜夜摸av| 欧美激情第1页| 久久这里有精品视频| 久久国产福利国产秒拍| 亚洲性视频h| 亚洲视频一区| 一区二区免费在线播放| 亚洲品质自拍| 亚洲人成啪啪网站| 亚洲国产精品视频一区| 欧美高清在线一区二区| 免费看av成人| 欧美国产欧美亚洲国产日韩mv天天看完整| 欧美一级电影久久| 欧美影院午夜播放| 久久er精品视频| 欧美在线中文字幕| 欧美呦呦网站| 久久久久久高潮国产精品视| 久久www免费人成看片高清| 欧美一区二粉嫩精品国产一线天| 亚洲天堂成人在线观看| 亚洲午夜av| 欧美亚洲一区二区三区| 欧美一区二区三区在| 久久久久久久一区二区| 久久免费少妇高潮久久精品99| 久久久久久网址| 免费欧美高清视频| 亚洲欧洲一区二区三区久久| 亚洲精品视频在线| 亚洲视频网站在线观看| 午夜精品久久久久久| 久久精品国产一区二区三区免费看 | 亚洲一区国产精品| 欧美一区二区观看视频| 久久九九久精品国产免费直播| 久久久久久亚洲精品不卡4k岛国| 久久天堂国产精品| 欧美精品一区二区三区久久久竹菊| 欧美福利视频网站| 国产精品夫妻自拍| 国产资源精品在线观看| 亚洲精品孕妇| 西西裸体人体做爰大胆久久久| 久久久精品欧美丰满| 亚洲电影毛片| 亚洲一级高清| 久久婷婷国产综合精品青草| 欧美精品亚洲二区| 久久爱www久久做| 亚洲午夜女主播在线直播| 欧美一区免费视频| 免费在线观看精品| 国产精品多人| 在线观看亚洲视频啊啊啊啊| 亚洲午夜成aⅴ人片| 另类春色校园亚洲| 亚洲最新视频在线| 久久婷婷成人综合色| 国产精品国产三级欧美二区 | 国产精品私人影院| 亚洲清纯自拍| 欧美永久精品| 夜夜嗨av一区二区三区四区| 欧美一区二区精品| 欧美日韩国产一区二区三区| 国产真实精品久久二三区| 一区二区三区免费网站| 蜜臀99久久精品久久久久久软件| 亚洲素人在线| 欧美精品色综合| 亚洲东热激情| 久久久久久9999| 亚洲欧美电影院| 欧美三级电影精品| 日韩一级大片在线| 欧美第十八页| 久久久91精品国产一区二区三区|