2017-03-01 113 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(); 
}