qicosmos / rest_rpc

modern C++(C++11), simple, easy to use rpc framework
MIT License
1.66k stars 365 forks source link

线程中一直调用rpcclient对象,一段时间后会报错segment fault #69

Open chenjinle opened 2 years ago

chenjinle commented 2 years ago

try{ rest_rpc::rpc_client rpcClient;

printf("start netTping...\n");

rpcClient.enable_auto_heartbeat(); // automatic heartbeat
rpcClient.connect("127.0.0.1", 8999, false, 60); // 60s

if (!rpcClient.has_connected()) {
    printf("Error:%s not connect\r\n", __FUNCTION__);
    return -1;
}

if(bAsync){
    auto f = rpcClient.async_call<rest_rpc::FUTURE>("netTping", sDeviceName, sDomainName, sDestIp, bExeCmd, nMaxPack);
    if (f.wait_for(std::chrono::milliseconds(milliseconds)) ==
        std::future_status::timeout) {
        printf("Error: %s : call timeout, line: %d\n", __FUNCTION__, __LINE__);
        return -2;
    } 

    stNetCommuPacketInfoRpc =  f.get().as<NETCOMMUPACKETINFORPC>();

}else{
    stNetCommuPacketInfoRpc = rpcClient.call<NETCOMMUPACKETINFORPC>("netTping", sDeviceName, sDomainName, sDestIp, bExeCmd, nMaxPack);
}

printf("netTping1111...\n");

}catch(std::exception &e){
    std::cout << e.what() << std::endl;
}

调试信息输出“netTping1111..” ,后面就是segment fault. 而且没有捕获到异常输出. 这个函数是创建了一个线程,一直执行调用,几十分钟后出现问题, 是否restrpc析构有问题还是什么原因?

qicosmos commented 2 years ago

是最新的master代码吗?能把例子写完整一点吗,把线程的代码写写一下。

chenjinle commented 2 years ago

int netTping(const std::string &sDeviceName, const std::string &sDomainName, const std::string &sDestIp,NETCOMMUPACKETINFO &stNetCommuPacketInfo, bool bExeCmd, int nMaxPack, bool bAsync, unsigned int milliseconds){

NETCOMMUPACKETINFORPC stNetCommuPacketInfoRpc;
try{
// rest_rpc::rpc_client &m_rpcClient = getrpcClient();
rest_rpc::rpc_client rpcClient;

//printf("start netTping...\n");

rpcClient.enable_auto_heartbeat(); // automatic heartbeat
rpcClient.connect("127.0.0.1", 8999, false, 60); // 60s

if (!rpcClient.has_connected()) {
    printf("Error:%s not connect\r\n", __FUNCTION__);
    return -1;
}

if(bAsync){
    auto f = rpcClient.async_call<rest_rpc::FUTURE>("netTping", sDeviceName, sDomainName, sDestIp, bExeCmd, nMaxPack);
    if (f.wait_for(std::chrono::milliseconds(milliseconds)) ==
        std::future_status::timeout) {
        printf("Error: %s : call timeout, line: %d\n", __FUNCTION__, __LINE__);
        return -2;
    } 

    stNetCommuPacketInfoRpc =  f.get().as<NETCOMMUPACKETINFORPC>();

}else{
    stNetCommuPacketInfoRpc = rpcClient.call<NETCOMMUPACKETINFORPC>("netTping", sDeviceName, sDomainName, sDestIp, bExeCmd, nMaxPack);
}

//printf("netTping1111...\n");

}catch(std::exception &e){
    std::cout << e.what() << std::endl;
}

if((-1 == stNetCommuPacketInfoRpc.nMaxPacketTransTime) &&
   (-1 == stNetCommuPacketInfoRpc.nMinPacketTransTime) &&
   (-1 == stNetCommuPacketInfoRpc.nAvgPacketTransTime) &&
   (-1 == stNetCommuPacketInfoRpc.nLostPackagePercentage)){

    return -1;
}

stNetCommuPacketInfo.nMaxPacketTransTime    = stNetCommuPacketInfoRpc.nMaxPacketTransTime;
stNetCommuPacketInfo.nMinPacketTransTime    = stNetCommuPacketInfoRpc.nMinPacketTransTime;
stNetCommuPacketInfo.nAvgPacketTransTime    = stNetCommuPacketInfoRpc.nAvgPacketTransTime;
stNetCommuPacketInfo.nLostPackagePercentage = stNetCommuPacketInfoRpc.nLostPackagePercentage;

//printf("end netTping...\n");
return 0;

}

这个就是那个完整的接口函数. 昨天继续调试,打印输出的信息是 ~rpc_client() { try{ printf(" ~rpc_client111\n"); close(); printf(" ~rpc_client222\n"); stop(); printf(" ~rpc_client333\n"); }catch(std::exception &e){ std::cout << e.what() << std::endl; } }

输出printf(" ~rpc_client111\n");之后,就没往下了,应该在close()函数里有什么问题吧?

qicosmos commented 2 years ago

线程呢?

qicosmos commented 2 years ago

是死循环不停的调用还是每隔几秒调用,能不能搞个简单完整的例子复现,否则我没法帮你。 可以添加附件文件的,把能复现的服务端和客户端的代码上传一下。

Codecing commented 1 year ago

是死循环不停的调用还是每隔几秒调用,能不能搞个简单完整的例子复现,否则我没法帮你。 可以添加附件文件的,把能复现的服务端和客户端的代码上传一下。

我猜测在循环中重复 rpc_client 的构造和析构,会导致对应的端口出现大量的 TIME_WAIT。导致无资源可用,所以崩溃闪退

qicosmos commented 1 year ago

每次循环都创建一个连接,死循环肯定会导致句柄耗尽的。