创建一个分离线程单独处理业务,为什么主UI线程还是卡死了

c++客户端 主线程(UI线程)里面开了一个std::thread detach运行,为什么会阻塞主线程?

前言:
在C++中,std::thread 对象在创建时可以设置为 detach 或 join 状态。

如果一个线程是 detach状态,那么当这个线程对象被销毁时,该线程会自动从主线程中分离出去,成为后台线程。这意味着主线程不再等待这个线程结束,而是可以继续执行。
如果一个线程是 join 状态(这是默认的),那么当这个线程对象被销毁时,主线程会阻塞,直到这个线程结束为止。

现在,如果你在主线程(UI线程)中创建了一个 std::thread 对象,并设置为 detach 状态,那么理论上,这个新线程不应该阻塞主线程。主线程应该能够继续执行其它任务,而新线程在后台运行。

然而,如果你的主线程(UI线程)被阻塞了,那么可能的原因可能不是由于 std::thread 的 detach 状态。可能的原因包括:

  1. 线程函数的问题:如果你的线程函数中有一些代码导致它无法结束或无法正确执行,那么即使线程是 detach 状态,也可能间接地导致主线程阻塞。
  2. UI线程和线程之间的交互:如果你的UI线程和新线程之间存在某种形式的交互(例如,共享资源、锁、条件变量等),那么可能存在竞态条件或死锁,导致主线程阻塞。
    线程库或操作系统的限制:在某些情况下,线程库或操作系统可能有一些限制或特性,导致 detach 状态的线程在某些情况下仍然会阻塞主线程。
  3. UI线程更新不当:如果在分离线程中直接更新UI元素,这可能会导致主UI线程卡死。因为UI元素的更新应该在主UI线程中完成,而不是在分离线程中。在WinForms或WPF中,需要使用Invoke或BeginInvoke来在UI线程中执行更新。
    为了确定具体原因,你需要检查以下几点:
  4. 线程函数的内容:确保线程函数中没有无限循环、死锁或任何可能导致线程无法结束的代码,因为它可能会消耗大量的系统资源,间接影响到主UI线程。
  5. 资源争用:如果分离线程和主UI线程争用相同的资源(如文件、数据库连接、内存等),并且没有适当地进行同步,那么可能会导致资源争用和死锁,从而影响主UI线程。
  6. 线程的状态和错误,线程异常处理不足:如果分离线程中的代码没有适当的异常处理机制,当遇到未处理的异常时,可能会导致线程崩溃或挂起,间接影响主UI线程。
  7. 高负载或资源不足:如果分离线程执行的任务非常重,或者系统资源不足,那么即使线程是分离的,也可能因为资源瓶颈导致主UI线程响应缓慢。
    总之,std::thread 的 detach 状态不应该导致主线程阻塞。如果发生了这种情况,那么问题可能出在线程函数或线程与主线程之间的交互上,或者线程异常。

一个应用程序线程的创建资源也是有上线的

如果程序不停的创建线程,那么运行一会可能会发生莫名的错误,使用GetLastError函数可以看到错误码值是8,翻译过来是内存资源不足。
所以不能在持续调用或进入的函数里面,通过创建线程分离去解除ui卡顿问题,因为每进入一次函数,就会创建一个新线程,如果这个函数100ms进入一次,那么要不了多久,内存资源就会炸了。
这个时候应该去找个合适的时机创建一个分离进程去持续的工作。既不会卡顿,又能处理业务。
在这里插入图片描述

使用分离线程,死循环处理业务导致内存占满

原因:cpu一直被独占没有被释放出来,即便是分离线程,也会使得内存占满,或者运行几次后内存占满。
解决方案:死循环里面要使用sleep,这样cpu可以分配碎片时间轮询所有线程,就解决了内存独占问题。性能可以得到提升。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值