由Lambda和线程池搭配引发的segment fault,顺便聊一下为什么java里的lambda设计成了按值传递

2022/6/15 1:22:31

本文主要是介绍由Lambda和线程池搭配引发的segment fault,顺便聊一下为什么java里的lambda设计成了按值传递,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

由lambda和线程池搭配引发的segment fault,顺便聊一下为什么java里的lambda设计成了按值传递

BUG属性:偶发型BUG,无法精准触发

 对bev的引用捕获,会因为bev存储的值随着堆栈的变化而发生SF

触发过程:多线程下的操作

  1. 线程池线程耗尽情况下,任务压进任务队列中存储
  2. 在轮到此任务执行时,触发segment fault

触发条件

  1. 压入的任务没有立即处理(其实就算立即处理也有可能触发SF)
  2. 任务引入了外部堆栈上的变量

总结:在利用lambda给线程池派发任务时,捕获变量最好使用pass by value;(假设入参是通过引用(指针1)传递进来的,可以再次通过引用(指针2)把值传递进lambda,(这里指针1和2归属于不同的堆栈地址上,但是所存储的值都是一样的), 只要这个内存空间原本就是在堆上,并且在执行lambda之前没有被回收,那么这块内存空间就是可访问的,但是需要很细心才能这样使用,使用前请了解清楚其用法带来的心智负担)

最后解决方式:将引发SF的变量通过pass by value传递进去

话题延伸:为什么java里的lambda设计成了按值传递?

假设java在使用保存并传递lambda时,堆栈弹栈了,并且lambda内部变量所引用的指针,所指向的地址发生了变化,就会引发异常。



这篇关于由Lambda和线程池搭配引发的segment fault,顺便聊一下为什么java里的lambda设计成了按值传递的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程