• <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>
            隨筆-1  評(píng)論-10  文章-0  trackbacks-0
              置頂隨筆

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

              我們知道Qt以他的signal和slot機(jī)制獨(dú)步天下。但大家在用的時(shí)候有沒(méi)有注意過(guò),signal和slot之間是異步的,還是同步的呢?為此我問(wèn)過(guò)不少使用Qt的道友。有人說(shuō)是同步的,有人說(shuō)是異步的,也有人說(shuō)要看當(dāng)時(shí)你的人品。:( #$%^&*

              為此貧道,特別做了以下幾個(gè)測(cè)試:

                 First,在main()主函數(shù)里,設(shè)置兩個(gè)基于QObject為父類(lèi)的對(duì)象a和b,a觸發(fā)signal,b接受signal。請(qǐng)看具體案例:

                

             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的函數(shù)里打個(gè)斷點(diǎn),看一下調(diào)用堆棧(call stack)。

            是同步調(diào)用的,某些道友開(kāi)始拈胡微笑,實(shí)踐出真知啊。

            此時(shí)只見(jiàn)東方黑云滾滾,電閃雷鳴,又有道友開(kāi)始度劫了。突然一度劫道友橫眉冷對(duì),拿起拂塵刷刷的改寫(xiě)了上面的代碼。只見(jiàn)此道友把a(bǔ)對(duì)象挪到了一個(gè)新線程中(MyTestC創(chuàng)建的),而b對(duì)象仍然在主線程中。然后a對(duì)象觸發(fā)信號(hào)。

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

            說(shuō)時(shí)遲,那時(shí)快。在一道紫雷劈下之際,按下了F5。只見(jiàn),此時(shí)的調(diào)用堆棧顯示,

            奇跡出現(xiàn)了,居然變成異步調(diào)用了。只見(jiàn)東方天空萬(wàn)道金光射下,在陣陣仙樂(lè)聲中,傳來(lái)朗朗之聲:"貧道塵事已了,再無(wú)牽掛"。

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

            在吾等眾人膜拜加疑惑之時(shí),只見(jiàn)飛升前輩,留下一條偈語(yǔ)。內(nèi)事不決問(wèn)百度,外事不決問(wèn)谷歌。

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

            原來(lái)signal和slot是異步調(diào)用還是同步調(diào)用,取決于對(duì)connect的設(shè)定。其實(shí)connect還有一個(gè)參數(shù)(Qt::ConnectionType),是它決定了是同步還是異步。以下是ConnectionType的定義

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

            非也,其實(shí)Auto是這樣規(guī)定的,

            當(dāng)sender和receiver在同一線程時(shí),就是同步模式,而在不同線程時(shí),則是異步模式。

            眾人皆曰善。

            就在眾人彈冠相慶之時(shí),突然一道類(lèi)似眼鏡發(fā)出的寒光閃過(guò),一個(gè)黑影漸漸清晰了起來(lái)。

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

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

            接著他刷刷的又改寫(xiě)了代碼,在主線程中生成a,b兩個(gè)對(duì)象,而a對(duì)象在新線程(MyTestC創(chuàng)建的)中觸發(fā)信號(hào)。

             

            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。只見(jiàn)調(diào)用堆棧(call stack)顯示

            眾人皆驚呼,“Impossible”。a和b明明是屬于一個(gè)線程的,為何會(huì)異步調(diào)用。此時(shí)我們熟悉的語(yǔ)錄,又在耳邊回響,是"我相信真相只有一個(gè)!!!"這句話嗎?No,只見(jiàn)柯南君,優(yōu)雅地?fù)]了揮手指,"Nothing impossible",從口中緩緩滑出。

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

            此時(shí)柯南君緩緩從口袋中,摸出一張紙,拋向空中,然后轉(zhuǎn)身離去。只見(jiàn)隨風(fēng)飄落的紙面上面摘錄了這么一段Qt源代碼,在Auto模式下,如果要同步調(diào)用,不僅要求sender和receiver是同一線程,而且sender觸發(fā)的時(shí)候,所在的線程也要和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眾人皆驚,原來(lái)在Auto模式下,如果sender的觸發(fā)時(shí)所處的線程和receiver不同,也會(huì)是異步調(diào)用。此時(shí)道友齊聲向柯南喊道“這是全部的真相了嗎”?柯南轉(zhuǎn)過(guò)頭來(lái)笑而不語(yǔ),漸漸又消失在黑暗中。“有多少無(wú)恥可以重來(lái)”漂上了眾人的心頭。望著遠(yuǎn)處的雨后陽(yáng)光,一個(gè)大大的問(wèn)號(hào)也出現(xiàn)在眾人頭頂,"Qt你到底有多無(wú)恥???"。眾人又陷入了沉思。

            欲知后事如何,請(qǐng)聽(tīng)下回分解。

             

            此篇已在CNBLOG同時(shí)發(fā)布

             

             

             

             

             

             




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

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

              我們知道Qt以他的signal和slot機(jī)制獨(dú)步天下。但大家在用的時(shí)候有沒(méi)有注意過(guò),signal和slot之間是異步的,還是同步的呢?為此我問(wèn)過(guò)不少使用Qt的道友。有人說(shuō)是同步的,有人說(shuō)是異步的,也有人說(shuō)要看當(dāng)時(shí)你的人品。:( #$%^&*

              為此貧道,特別做了以下幾個(gè)測(cè)試:

                 First,在main()主函數(shù)里,設(shè)置兩個(gè)基于QObject為父類(lèi)的對(duì)象a和b,a觸發(fā)signal,b接受signal。請(qǐng)看具體案例:

                

             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的函數(shù)里打個(gè)斷點(diǎn),看一下調(diào)用堆棧(call stack)。

            是同步調(diào)用的,某些道友開(kāi)始拈胡微笑,實(shí)踐出真知啊。

            此時(shí)只見(jiàn)東方黑云滾滾,電閃雷鳴,又有道友開(kāi)始度劫了。突然一度劫道友橫眉冷對(duì),拿起拂塵刷刷的改寫(xiě)了上面的代碼。只見(jiàn)此道友把a(bǔ)對(duì)象挪到了一個(gè)新線程中(MyTestC創(chuàng)建的),而b對(duì)象仍然在主線程中。然后a對(duì)象觸發(fā)信號(hào)。

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

            說(shuō)時(shí)遲,那時(shí)快。在一道紫雷劈下之際,按下了F5。只見(jiàn),此時(shí)的調(diào)用堆棧顯示,

            奇跡出現(xiàn)了,居然變成異步調(diào)用了。只見(jiàn)東方天空萬(wàn)道金光射下,在陣陣仙樂(lè)聲中,傳來(lái)朗朗之聲:"貧道塵事已了,再無(wú)牽掛"。

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

            在吾等眾人膜拜加疑惑之時(shí),只見(jiàn)飛升前輩,留下一條偈語(yǔ)。內(nèi)事不決問(wèn)百度,外事不決問(wèn)谷歌。

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

            原來(lái)signal和slot是異步調(diào)用還是同步調(diào)用,取決于對(duì)connect的設(shè)定。其實(shí)connect還有一個(gè)參數(shù)(Qt::ConnectionType),是它決定了是同步還是異步。以下是ConnectionType的定義

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

            非也,其實(shí)Auto是這樣規(guī)定的,

            當(dāng)sender和receiver在同一線程時(shí),就是同步模式,而在不同線程時(shí),則是異步模式。

            眾人皆曰善。

            就在眾人彈冠相慶之時(shí),突然一道類(lèi)似眼鏡發(fā)出的寒光閃過(guò),一個(gè)黑影漸漸清晰了起來(lái)。

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

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

            接著他刷刷的又改寫(xiě)了代碼,在主線程中生成a,b兩個(gè)對(duì)象,而a對(duì)象在新線程(MyTestC創(chuàng)建的)中觸發(fā)信號(hào)。

             

            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。只見(jiàn)調(diào)用堆棧(call stack)顯示

            眾人皆驚呼,“Impossible”。a和b明明是屬于一個(gè)線程的,為何會(huì)異步調(diào)用。此時(shí)我們熟悉的語(yǔ)錄,又在耳邊回響,是"我相信真相只有一個(gè)!!!"這句話嗎?No,只見(jiàn)柯南君,優(yōu)雅地?fù)]了揮手指,"Nothing impossible",從口中緩緩滑出。

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

            此時(shí)柯南君緩緩從口袋中,摸出一張紙,拋向空中,然后轉(zhuǎn)身離去。只見(jiàn)隨風(fēng)飄落的紙面上面摘錄了這么一段Qt源代碼,在Auto模式下,如果要同步調(diào)用,不僅要求sender和receiver是同一線程,而且sender觸發(fā)的時(shí)候,所在的線程也要和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眾人皆驚,原來(lái)在Auto模式下,如果sender的觸發(fā)時(shí)所處的線程和receiver不同,也會(huì)是異步調(diào)用。此時(shí)道友齊聲向柯南喊道“這是全部的真相了嗎”?柯南轉(zhuǎn)過(guò)頭來(lái)笑而不語(yǔ),漸漸又消失在黑暗中。“有多少無(wú)恥可以重來(lái)”漂上了眾人的心頭。望著遠(yuǎn)處的雨后陽(yáng)光,一個(gè)大大的問(wèn)號(hào)也出現(xiàn)在眾人頭頂,"Qt你到底有多無(wú)恥???"。眾人又陷入了沉思。

            欲知后事如何,請(qǐng)聽(tīng)下回分解。

             

            此篇已在CNBLOG同時(shí)發(fā)布

             

             

             

             

             

             




            posted @ 2011-08-26 10:41 櫻桃小錘子 閱讀(12945) | 評(píng)論 (10)編輯 收藏
            僅列出標(biāo)題  
            久久国产免费直播| 日韩久久无码免费毛片软件| 午夜精品久久久久| 久久精品亚洲男人的天堂| 久久成人国产精品免费软件| 久久男人AV资源网站| 久久久精品久久久久久| 久久AⅤ人妻少妇嫩草影院| 91精品日韩人妻无码久久不卡| 狠狠色丁香婷婷久久综合不卡| 国产∨亚洲V天堂无码久久久| 69国产成人综合久久精品| 欧美777精品久久久久网| 久久精品国产亚洲av瑜伽| 亚洲午夜精品久久久久久app| 免费精品久久天干天干| 久久午夜伦鲁片免费无码| 久久久久国产精品| 欧美精品丝袜久久久中文字幕| 久久久无码精品亚洲日韩京东传媒| 亚洲级αV无码毛片久久精品| 国产精品对白刺激久久久| 99久久国产免费福利| 四虎久久影院| 久久国产亚洲高清观看| 亚洲嫩草影院久久精品| 久久人人青草97香蕉| 狠狠色婷婷久久一区二区三区| 国产成人香蕉久久久久| 熟妇人妻久久中文字幕| 狠狠久久综合| 国产成人精品免费久久久久| 欧美久久一区二区三区| 久久久久久久综合日本亚洲| 亚洲精品无码久久不卡| 色噜噜狠狠先锋影音久久| 国产成人久久精品一区二区三区| 成人国内精品久久久久影院VR| 亚洲国产精品久久电影欧美| 久久精品不卡| 国产成人久久精品二区三区|