2010-10-02 44 views
1

我有一個Qt應用程序,它有兩個線程:處理GUI的主線程和管理網絡連接的第二個線程。下面是線程代碼:爲什麼從主線程調用槽?

void thread::run() 
{ 
    QTcpServer server; 

    server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect())); 

    //... 
} 

當我把一個斷點在OnConnect()開始和調試應用程序,它宣佈OnConnect()正在從主線程調用!

我該如何讓OnConnect()QTcpServer在同一個線程中運行?

回答

4

爲了給出更徹底的答案,請深入探討信號時隙連接和線程上下文如何相互作用。基本上,對於更多的連接(自動連接),如果發射器和接收器都在相同的線程環境中,則直接調用該插槽,否則將是排隊連接,並且插槽將在線程上下文中運行包含插槽的對象。在這種情況下,它必須排隊,這意味着你的線程是主應用程序線程上下文的一部分,而不是它自己的線程上下文。這得到了the documentation的強化Qt提供了對其線程的概述,其中指出QThread實例由創建它的線程上下文「擁有」,而不是它所表示的線程上下文。這意味着您有三個主要選擇:

  1. 您可以使用moveToThread()將線程移動到其自己的上下文中。請注意,刪除線程時可能會導致問題,除非將其移回到將被銷燬的上下文中,並且這隻能在源線程上下文中完成,因此必須在退出運行函數之前完成。
  2. 您可以將QThread實例視爲線程的句柄,而不是將其作爲線程本身的一部分。如果您需要在新線程的上下文中完成某些工作,請創建一個不同的對象來處理這些對象,並在新線程的上下文(運行函數內)中對其進行實例化。這是我會推薦的。
  3. 強制直接連接。這意味着您需要確保在插槽中運行的代碼是線程安全的,而忽略Qt內置的使這些函數線程安全的方法。 This is what you have done
0

看來問題是我沒有通過Qt::DirectConnection作爲connect()的最後一個參數。

添加後,它工作。

相關問題