自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Qt中實(shí)現(xiàn)QThread線程同步QFtp

移動(dòng)開(kāi)發(fā)
本文講述的是在Qt中如何實(shí)現(xiàn)QThread線程同步QFtp,那么對(duì)于QFtp,它是一個(gè)用來(lái)實(shí)現(xiàn)FTP協(xié)議的類,#include <qftp.h> 繼承了QNetworkProtocol。本文由介紹。

Qt中實(shí)現(xiàn)QThread線程同步QFtp ,對(duì)于QFtp,它是一個(gè)用來(lái)實(shí)現(xiàn)FTP協(xié)議的類,詳情查閱資料。接觸Qt沒(méi)有多長(zhǎng)時(shí)間,但簡(jiǎn)單幾個(gè)小例子已經(jīng)讓我感受到Qt在C++運(yùn)用方面的強(qiáng)大。寫了一個(gè)小程序,需要在一個(gè)單獨(dú)的線程中使用QFtp來(lái)獲取FTP服務(wù)器上面的文件。FTP是FileZilla。

有兩個(gè)問(wèn)題我比較關(guān)心:

(1)QThread到底如何使用

(2)QFtp是Async(異步)操作,也就是說(shuō)例如connectToHost這樣的函數(shù)都是立刻返回,當(dāng)操作完成后QFtp會(huì)發(fā)出signal。然而既然我的Ftp操作是在一個(gè)單獨(dú)的線程,我想寫一個(gè)函數(shù)downloadFtpFile() 來(lái)完成從connect到login到下載文件等一系列的操作,然后再返回。相當(dāng)于我需要Sync(同步)的操作,所以需要等待(block)每個(gè)Ftp命令的結(jié)果。

在該文章最后有一個(gè)推薦的使用QThread的方法。我在這里想補(bǔ)充一點(diǎn):obj.moveToThread(&thread); 這句話將obj從主線程移動(dòng)到了thread對(duì)象所在的線程。但如果obj的對(duì)象里面有其他的變量,那么這些變量是在主線程中生成的。所以如果這些變量中有類變量,不能將obj的this指針作為parent傳給他們。

對(duì)于第二個(gè)問(wèn)題,我使用了QSemaphore類來(lái)完成我的block和同步操作:在slot函數(shù)里面接收QFtp命令執(zhí)行結(jié)果的signal,釋放信號(hào),同時(shí)downloadFtpFile()函數(shù)里在調(diào)用完每一個(gè)QFtp異步命令后等待信號(hào)。在有點(diǎn)令人失望的是QSemaphore在通過(guò)tryAcquire()等待信號(hào)的時(shí)候是不處理事件event的。但是我需要在等待的時(shí)候程序也能觸發(fā)slot,告訴我當(dāng)前命令的執(zhí)行情況。所以我使用了一個(gè)小循環(huán),里面調(diào)用qApp->processEvents();來(lái)讓我的slot函數(shù)被觸發(fā)。下面是代碼例子(只是樣例,并不完全符合C++語(yǔ)法):

首先是我的下載Ftp文件的函數(shù):

 

  1. downloadFtpFile () //該函數(shù)在單獨(dú)線程里執(zhí)行     
  2. {     
  3.      int m_idFtpOp; // 該變量用來(lái)存放每一個(gè)QFtp命令I(lǐng)D     
  4.      int nVal;     
  5.      QFtp*pFtp=newQFtp (this); // 生成QFtp工具對(duì)象     
  6.      connect (pFtp,SIGNAL(listInfo(QUrlInfo)),this,SLOT(slotFtpListInfo(QUrlInfo))); // 我們需要listinfo,因?yàn)槲覀冃枰螺dftp所有當(dāng)前目錄文件     
  7.      connect (pFtp,SIGNAL(commandFinished(int,bool)),this,SLOT(slotFtpCmdFinished(int,bool)));   
  8. // 每個(gè)QFtp命令完成之后,會(huì)發(fā)出commandFinished信號(hào),我們?cè)诓酆瘮?shù)中處理該信號(hào)  
  9.      m_idFtpOp = pFtp->connectToHost (<FTP地址>, 21); // 連接到遠(yuǎn)程FTP Server     
  10.      bRet=false;     
  11.      nVal=100;     
  12.      while (bRet == false) // 使用nVal變量來(lái)做一個(gè)10000ms(10s)的超時(shí)     
  13.      {     
  14.            nVal--;     
  15.            if (nVal == 0)     
  16.                 break;     
  17.            qApp->processEvents();   // 這里每100ms處理一次event,使slot函數(shù)能夠被調(diào)用     
  18.            bRet=m_SemOp.tryAcquire (1,100); // 等待信號(hào)100ms     
  19.      }     
  20.     if (!bRet || m_bFtpOpError)   // 如果超時(shí),或者slot函數(shù)中將m_bFtpOpError置成true,則關(guān)閉Ftp,返回錯(cuò)誤     
  21.       {     
  22.            pFtp->abort();     
  23.            pFtp->deleteLater();     
  24.            return ERRCODE_FCC_FTP_CONN_TIMEOUT;     
  25.      }     
  26. }   

下面是槽函數(shù)

  1. slotFtpCmdFinished (int id, bool error)     
  2. {     
  3.          if (m_idFtpOp == id)  // 如果返回的id是當(dāng)前正在操作的命令     
  4.          {     
  5.                   if (error)     
  6.                            m_bFtpOpError=true;     
  7.                   else    
  8.                            m_bFtpOpError=false;     
  9.                   m_SemOp.release();  // 釋放信號(hào)(使downloadFtpFile函數(shù)中m_SemOp.tryAcquire()返回true)     
  10.          }     
  11. }   

以上的代碼只演示了對(duì)QFtp第一個(gè)命令connectToHost的等待過(guò)程。下面的login,list,get等操作都使用這個(gè)方法。

注意:在此例中,QFtp是在當(dāng)前線程生成的,所以信號(hào)listInfo(QUrlInfo)的connect方式是direct連接。如果QFtp是在另一個(gè)線程生成(比如說(shuō)是在函數(shù)downloadFtpFile所在類的構(gòu)造函數(shù)中),那么第一:不能將this指針作為parent傳給QFtp對(duì)象,第二:需要使用qRegisterMetaType<QUrlInfo>("QUrlInfo");來(lái)注冊(cè)QUrlInfo類,因?yàn)樾盘?hào)發(fā)射與接收在不通的線程中,信號(hào)使用queued的方式。如果不注冊(cè)QURlInfo類,會(huì)在運(yùn)行時(shí)動(dòng)態(tài)報(bào)告錯(cuò)誤。

總結(jié):本文介紹的是在Qt中如何實(shí)現(xiàn)QThread線程同步QFtp ,看過(guò)本文之后,如果對(duì)于QThread不了解的話,那么請(qǐng)參考Qt中QThread使用方法這篇文章。使用本文介紹的方法,可以在獨(dú)立的線程中用同步的方式使用QFtp。在某些場(chǎng)合,尤其是采用應(yīng)答機(jī)制的系統(tǒng)中,這樣的實(shí)現(xiàn)可以很大程度上簡(jiǎn)化程序流程。

【編輯推薦】

淺談Qt中多線程編程

Qt環(huán)境變量配置與安裝

在Linux中設(shè)置Qt環(huán)境變量

用C#實(shí)現(xiàn)HTTP協(xié)議下的多線程文件傳輸

C#常用線程同步方法應(yīng)用場(chǎng)景和實(shí)現(xiàn)原理

責(zé)任編輯:zhaolei 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-06-14 10:18:58

QThread Qt 線程

2011-06-30 18:15:36

Qt 線程 同步

2011-06-20 13:43:08

Qt Socket 線程

2011-06-24 11:03:31

Qt 多線程 線程

2011-06-24 11:12:39

Qt 多線程 線程

2011-06-30 17:51:17

QT 元類型 線程

2011-06-22 15:24:50

Qt 線程

2011-06-22 15:42:18

QT 信號(hào)

2011-06-13 10:03:19

Qt 多線程 編程

2011-06-30 11:23:29

Qt 線程

2011-06-30 17:31:32

Qt 多線程 信號(hào)

2010-03-18 14:36:46

Java線程同步

2011-06-13 17:46:07

Qt 串口通信

2010-01-21 11:27:30

linux多線程機(jī)制線程同步

2011-06-22 10:12:08

Qt 線程

2010-03-03 17:52:31

Python線程同步

2010-04-21 15:20:31

Unix線程

2011-06-28 15:18:45

Qt 單例模式

2009-03-24 08:56:23

數(shù)據(jù)同步多線程Java

2009-07-01 17:34:03

Servlet和JSP
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)