程序有一个比较耗时的连接线程Connect()
在1s的定时器中,判断是否是否连接失败了,如果连接失败了就再调用Connect。在这里该如何判断Connect是否已经执行完毕呢?
直接使用Join阻塞了定时器并不可取。
我的思路是加个正在连接标志,连接之前true,连接完成后false。当定时器中检测到false的时候再执行join,但发现还是有一定时间的阻塞。
这个该如何解决?
不放代码确实不明白你的程序逻辑, 如果是我设计一个 connect 函数, 会返回一个 bool 看是否连接成功, 耗时阻塞没有问题, 放 promise 里, 不用定时器, 直接用 future wait 1 秒, 如果 ready 就 get value, true 就干接下来的事, false 就 接着 connect, 如果 future wait 1 秒没有 ready, 再分情况讨论, 继续等, 或其它. 有定时器逻辑差不多, 只不过必须死等 1 秒, 再次判断.
#include <chrono>
#include <iostream>
auto Connect() -> bool
{
return true;
}
void doSomething()
{
std::cout << "OK" << std::endl;
}
void doOthers()
{
std::cout << "PlanB" << std::endl;
}
auto main() -> int
{
std::promise<bool> prms;
std::future<bool> ftr = prms.get_future();
std::thread thrd([prms = std::move(prms)]() mutable {
bool const connectSuccess = Connect();
prms.set_value(connectSuccess);
});
thrd.detach();
std::this_thread::sleep_for(std::chrono::seconds(1));
if ((ftr.wait_for(std::chrono::seconds(0)) == std::future_status::ready) &&
ftr.get())
{
doSomething();
}
else
{
doOthers();
}
return 0;
}
这种最好把connect fd设置非阻塞模式。然后再结合定时器。如果connect失败在非阻塞模式下会立即返回 再起动定时1秒后重新连
可以利用信号来处理
https://blog.csdn.net/m0_56827172/article/details/124895395
不知这里提到的方法思路是否能帮到你,链接:https://segmentfault.com/q/1010000042693101/
用标志位变量可以解决的,定时器检测造成的延时最长就1s左右。如果你的需求是线程退出就要立马告诉其他线程进行join处理的话,要么有一个线程join等待,要是Linux环境下的,可以使用信号
1 不使用线程池的情况下
调用Thread.isAlive()方法,如果该线程没有执行完毕,会返回true;
调用Thread.activeCount()方法,返回当前线程组的运行线程数量,一般是1,可是IDEA执行用户代码的时候,实际是通过反射方式去调用,而与此同时会创建一个Monitor Ctrl-Break 用于监控目的。
2 使用线程池的情况下
在线程池的线程启动后,执行线程池的shutdown()方法,该方法表示当线程池中所有线程都运行完毕后就关闭线程池。再使用线程池的isTerminated()方法判断线程池是否已经关闭判断线程是否执行完毕。
使用一些信号量,比如CountDownLatch或者condition等。
这场景就是多线程同步。
Connect既然是阻塞模式,它应该有超时时间参数(这种是常规套路);否则调用后就一直等待,直到连接成功。
通常可以使用std::mutex+std::condition_variable来完成C++11多线程之间的同步操作,比如:
在你的等待线程T1中,创建并启动了连接线程T2(Connect业务);
T1中启动T2成功后,进入等待状态,直到收到T2连接成功的事件通知,接着处理后续逻辑;
T2线程函数中While循环调用Connect(超时调用),通过返回值可以判断是否连接成功,若连接成功,cv.notify_one通知T1,结束T2线程;若没连接成功,进入下一次Connect。
std::mutex+std::condition_variable的具体用法,可以参考这篇博客,用法比较简单
https://blog.csdn.net/zengyubao1/article/details/112754693
1,优化代码设计,避免这种情况
2,使用状态机来控制流程运行
3,使用条件变量进行事件通知
用个代理,给一个触发点,我之前用线程thread和定时器配合不怎么好用