有时候调用别人的程序一直不返回,造成卡死,后续程序无法处理,比如,我们通过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语句, 所以就不会调用线程函数作用域内申请的类对象的析构函数, 会造成内存泄露.