有时候调用别人的程序一直不返回,造成卡死,后续程序无法处理,比如,我们通过grpc_client来连接仿真服务器,但是在生成env = new Environment(ipAddress)的时候,一直不返回,后续我们无法处理。所以,我想着怎么控制该调用在一定时间内返回或者超时处理。对于这种情况,我们无法使用多次尝试的方式,因为代码不是我们的,我们无法进入里面设置超时等。经过调研,基本的可行方式是将该函数调用扔到一个线程中,通过线程超时来控制该函数调用。主要有两种方式,一种使用C++ 11提供的标准方式,一种使用boost库。

可以生成boost::thread来调用API:
boost::thread api_caller(::api_function, arg1, arg2);
if (api_caller.timed_join(boost::posix_time::milliseconds(500)))
    // API call returned within 500ms
    // API call timed out
但是,Boost不允许您终止工作线程。在此示例中,它只是孤立的。
您必须注意该API调用的作用,因为它可能永远不会释放所获取的资源。

或者使用条件变量:

#include "boost/thread.hpp"
#include "boost/thread/mutex.hpp"
#include "boost/thread/condition.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
//----------------------------------------------------------
boost::mutex g_mutexWait;               // 互斥锁
boost::condition_variable g_condWait;   // 条件变量
//----------------------------------------------------------
///< 输入数据线程函数
void InputThread()
    std::cout << "请在10秒内输入任意字符:" << std::endl;
    // 等待手工输入
    std::string strInputData = "";
    std::cin >> strInputData;
    // 输入了字符,则发出通知
    if (strInputData != "")
        g_condWait.notify_one();
//----------------------------------------------------------
///< 主函数
int main(int argc, char* argv[])
        // 启动线程输入数据
        boost::thread threadInput(InputThread);
        // 取得当前时间
        time_t tmInputStart = time(NULL);
        // 使用条件变量,等待输入数据
        //boost::unique_lock<boost::mutex> lockWait(g_mutexWait);
        boost::mutex::scoped_lock lockWait(g_mutexWait);
        bool bRet = g_condWait.timed_wait(lockWait, boost::get_system_time() + boost::posix_time::seconds(10));
        // 消息接收超时
        if (bRet == false)
            std::cout << "您输入的太慢了!请输入任意字符退出程序!" << std::endl;
        else // 接收到条件变量信号,未超时
            time_t tmInputEnd = time(NULL);
            std::cout << "您输入的太快了!只用了" << (tmInputEnd - tmInputStart) << "秒!" << std::endl;
        // 等待线程退出
        threadInput.join();
    catch (std::exception &ex)
        std::cout << ex.what() << std::endl;
    system("PAUSE");
    return 0;
//----------------------------------------------------------

使用C++ 11的标准库:

#include <stdlib.h>
#include <string>
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
//----------------------------------------------------------
std::mutex g_mutexWait;                 // 互斥锁
std::condition_variable g_condWait;     // 条件变量
//----------------------------------------------------------
///< 输入数据线程函数
void InputThread()
    std::cout << "请在10秒内输入任意字符:" << std::endl;
    // 等待手工输入
    std::string strInputData = "";
    std::cin >> strInputData;
    // 输入了字符,则发出通知
    if (strInputData != "")
        g_condWait.notify_one();
//----------------------------------------------------------
///< 主函数
int main(int argc, char* argv[])
        // 启动线程输入数据
        std::thread threadInput(InputThread);
        // 取得当前时间
        time_t tmInputStart = time(NULL);
        // 使用条件变量,等待输入数据
        std::unique_lock<std::mutex> lockWait(g_mutexWait);
        std::cv_status cvsts = g_condWait.wait_for(lockWait, std::chrono::seconds(10));
        // 消息接收超时
        if (cvsts == std::cv_status::timeout)
            std::cout << "您输入的太慢了!请输入任意字符退出程序!" << std::endl;
        else // 接收到条件变量信号,未超时
            time_t tmInputEnd = time(NULL);
            std::cout << "您输入的太快了!只用了" << (tmInputEnd - tmInputStart) << "秒!" << std::endl;
        // 等待线程退出
        threadInput.join();
    catch (std::exception &ex)
        std::cout << ex.what() << std::endl;
    system("PAUSE");
    return 0;
//----------------------------------------------------------
有时候调用别人的程序一直不返回,造成卡死,后续程序无法处理,比如,我们通过grpc_client来连接仿真服务器,但是在生成env = new Environment(ipAddress)的时候,一直不返回,后续我们无法处理。所以,我想着怎么控制该调用在一定时间内返回或者超时处理。对于这种情况,我们无法使用多次尝试的方式,因为代码不是我们的,我们无法进入里面设置超时等。经过调研,基本的可行方式是将该函数调用扔到一个线程中,通过线程超时来控制该函数调用。主要有两种方式,一种使用C++ 11提供的标准方式,一种 time_t cur_time = time(NULL); while(data.size() == 0 && static_cast<time_t>(cur_time + timeout) > time(NULL)) this->Recv(data);
本文实例讲述了 C++ 设置 超时 时间的简单实现方法,代码简单易懂,功能实用。分享给大家供大家参考。具体实现方法如下: 代码如下:BOOL SetTimeOut(SOCKET s, int nTime, BOOL bRecv)      int ret = ::setsockopt(s, SOL_SOCKET, bRecv?SO_RCVTIMEO:SO_SNDTIMEO, (char*)nTime, sizeof(nTime));      return ret!=SOCKET_ERROR;  此处setsockopt为针对套接口的操作,感兴趣的朋友可以查阅相关资料做进一步了解。
getchar()函数返回的是int类型,而不是返回char类型。直接使用while(ch = getchar())会导致接收不到结束符号,直到读取到上限才停止。需要显式注明结束标识EOF。 正确的使用方法应当是: while(ch = getchar()!=EOF) enum class cv_status { timeout, no_timeout }; class condition_variable; class condition_variable_any;
在做pat的时候,遇到 超时 问题,首先考虑算法问题,当算法没问题的时候,就要考虑输入输出问题,cin和cout的效率比较低,有两种解决方法。 1.把cin和cout改为scanf和printf 2.不改动cin和cout,在代码 加入代码段:ios::sync_with_stdio(false); 这个代码段可以大大提高cin和cout的效率问题。
1.可能是使用了cin cout 此时换成printf 和 scanf可以试试 原因:默认的时候cin与stdin总是保持同步,同时cout和stdout也一样,两者混用不会输出顺序错乱。对两者的兼容性导致cin有许多额外的开销。 禁用这个特性的语句是 std::ios::sync_with_stdio(false); 但是提速后仍然慢于 scanf printf TCP和UDP包装器。 DNSandHttp:DNS查询和http支持,基于基数树的Http路由。 uv-cpp语言翻译:Englishi简体 文uv-cpp是一个简单的界面,基于C ++ 11的高性能网络库。 依赖项libuv具有C ++ 11功能/绑定样式回调,而不是C样式函数指针。 TCP和UDP包装器。 DNSandHttp:DNS查询和http支持,基于基数树的Http路由。 TimerandTimerWheel:心跳 超时 判断,时间复杂度为O(1)。 异步:libuv异步包装器,但优化了多次调用但回调的问题
退出线程可以有四种方法: 1.线程函数的return返回(最好这样):其 用线程函数的return返回, 而终止线程是最安全的, 在线程函数return返回后, 会清理函数内申请的类对象, 即调用这些对象的析构函数. 然后会自动调用 _endthreadex()函数来清理 _beginthreadex(…)函数申请的资源(主要是创建的tiddata对象). 2.调用 _endthreadex()函数 或 ExitThread()函数(最好不要):如果使用这两种方法退出线程, 则不会执行线程函数的return语句, 所以就不会调用线程函数作用域内申请的类对象的析构函数, 会造成内存泄露.