2017-03-01 110 views
-1

我正在使用客戶端與服務器進行阻塞通信。該函數正在一個線程中運行。我想設置超時功能。我沒有使用提升或類似的東西。我正在使用Windows線程庫。如何在線程中運行的函數中設置超時

這裏是我想設置超時功能的功能。

bool S3W::IWFSData::WaitForCompletion(unsigned int timeout) 
{ 

    if (m_Buffer) 
    { 
     while (!m_Buffer.IsEmpty()) 
     { 
      unsigned int i = 0; 
      char gfname[255]; // must be changed to SBuffer 
      char minHeightArr[8], maxHeightArr[8], xArr[8], yArr[8]; 

      m_PingTime += timeout; 

      if (m_PingTime > PONG_TIMEOUT) 
      { 
       m_PingTime = 0; 
       return false; 
      } 

      while (m_Buffer[i] != '\0') 
      { 
       gfname[i] = m_Buffer[i]; 
       i++; 
      } 

      gfname[i] = '\0'; 

      for (unsigned int j = 0; j < 8; j++) 
      { 
       minHeightArr[j] = m_Buffer[i++]; 
      } 

      for (unsigned int j = 0; j < 8; j++) 
      { 
       maxHeightArr[j] = m_Buffer[i++]; 
      } 

      double minH = *(double*)minHeightArr; 
      double maxH = *(double*)maxHeightArr; 

      for (unsigned int j = 0; j < 8; j++) 
      { 
       xArr[j] = m_Buffer[i++]; 
      } 

      for (unsigned int j = 0; j < 8; j++) 
      { 
       yArr[j] = m_Buffer[i++]; 
      } 

      double x = *(double*)xArr; 
      double y = *(double*)yArr; 

      OGRFeature *poFeature = OGRFeature::CreateFeature(m_Layer->GetLayerDefn()); 

      if(poFeature) 
      { 
       poFeature->SetField("gfname", gfname); 
       poFeature->SetField("minHeight", minH); 
       poFeature->SetField("maxHeight", maxH); 

       OGRPoint point; 
       point.setX(x); 
       point.setY(y); 

       poFeature->SetGeometry(&point); 


       if (m_Layer->CreateFeature(poFeature) != OGRERR_NONE) 
       { 
        std::cout << "error inserting an area" << std::endl; 
       } 
       else 
       { 
        std::cout << "Created a feature" << std::endl; 
       } 
      } 

      OGRFeature::DestroyFeature(poFeature); 

      m_Buffer.Cut(0, i); 
     } 
    } 

    return true; 
} 

有是數據設定到緩衝器

int S3W::ImplConnection::Thread(void * pData) 
{ 
    SNet::SAutoLock lockReader(m_sLock); 
    // RECEIVE DATA 
    SNet::SBuffer buffer; 
    m_data->SrvReceive(buffer); 


    // Driver code for inserting data into the buffer in blocking communication 
    SNet::SAutoLock lockWriter(m_sLockWriter); 
    m_data->SetData("ahmed", strlen("ahmed")); 
    double minHeight = 10; 
    double maxHeight = 11; 
    double x = 4; 
    double y = 2; 
    char minHeightArr[sizeof(minHeight)]; 
    memcpy(&minHeightArr, &minHeight, sizeof(minHeight)); 


    char maxHeightArr[sizeof(maxHeight)]; 
    memcpy(&maxHeightArr, &maxHeight, sizeof(maxHeight)); 


    char xArr[sizeof(x)]; 
    memcpy(&xArr, &x, sizeof(x)); 


    char yArr[sizeof(y)]; 
    memcpy(&yArr, &y, sizeof(y)); 

    m_data->SetData(minHeightArr, sizeof(minHeightArr)); 
    m_data->SetData(maxHeightArr, sizeof(maxHeightArr)); 
    m_data->SetData(xArr, sizeof(xArr)); 
    m_data->SetData(yArr, sizeof(yArr)); 

    m_data->WaitForCompletion(1000); 


    return LOOP_TIME; 
} 
+0

爲什麼否定我的問題沒有說原因 – andre

+0

好像你還沒有完整的功能在這裏(非平衡塊,沒有其他部分)。 BTW,這是阻塞部分? – Jarod42

+0

@andre只是猜測:可能是因爲您沒有提供最小,完整和可驗證示例(http://stackoverflow.com/help/mcve),請編輯您的問題以幫助我們爲您提供幫助。 – roalz

回答

1

一般情況下,你不應該使用線程爲這些目的,因爲當終止這樣的線程時,進程和其他線程可能處於未知狀態。請看here的解釋。

因此,請考慮使用procceses。閱讀有關在C++中打開進程的here

如果您確實想要使用線程,您可以在超時後退出線程。

製作一個循環(如您所見),在一段時間後break

#include <ctime> 

#define NUM_SECONDS_TO_WAIT 5 

// outside your loop 

std::time_t t1 = std::time(0); 

// and in your while loop, each iteration: 

std::time_t t2 = std::time(0); 
if ((t2 - t1) >= NUM_SECONDS_TO_WAIT) 
{ 
    break; // ... 
} 
0

可以具有其保持時間標記一類構件的螺紋(當超時,其值設置爲currentTime + intervalToTimeout)。在WaitForCompletion()中,獲取當前時間並與超時時間進行比較。

我假設在您的代碼中,m_PingTime是您開始溝通的時間。你想在1000毫秒後超時。你需要做的是,在WaitForCompletion()

while (!m_Buffer.IsEmpty()) 
{ 
    ... 
    long time = getCurrentTime(); // fake code 
    if (m_PingTime + timeout < time) 
    { 
     m_PingTime = 0; 
     return false; 
    } 
    ... 
} 
+0

請問您能顯示一個僞代碼嗎?我應該使用timeGetTime()嗎? – andre

-1

這是我做的事,如果你想實現它自己:

clock_t startTime = clock(); 
clock_t timeElapsed; 
double counter; 
while(true){ 
    if(counter>=10){ 
     //do what you want upon timeout, in this case it is 10 secs 
    } 
    startTime = clock(); 
}