多线程锁的正确维护
堵塞物
以下是系统中存在的所有锁,以及它们用于避免潜在死锁的机制(Straus算法在这里是不可接受的)。
下面的锁绝对是最终锁(第一级),不应该尝试获取任何其他锁。
安全点
请注意,此锁由`JL_LOCK`和`JL_UNLOCK’隐式获取。 使用`_NOGC’选项来消除1级锁的这种情况。
持有此锁时,代码不应执行任何分配或到达安全点。 请注意,在分配、启用或禁用垃圾回收、输入或恢复异常帧以及接受或释放锁时都有安全点。
shared_map的
终结者
pagealloc
gc_perm_lock
flisp的
jl_in_stackwalk(Win32)
ResourcePool<?>::互斥锁
RLST_mutex
llvm打印互斥
jllockedstream::互斥锁
debuginfo_asyncsafe
推理timingmutex
执行引擎::会话锁
flisp本身已经是线程安全的。 此锁仅保护池’jl_ast_context_list_t'。 同样,ResourcePool<?>::互斥锁仅保护关联的资源池。
下面是最终的锁(第二级),它内部只接收第一级(安全点)的锁。
全局根锁
模块->锁
JLDebuginfoPlugin::PluginMutex
新推断互斥
下面是一个3级锁,只能在内部接收1级或2级锁。
方法->writelock
打字机,打字机
下面是一个4级锁,它只能递归地接收1级、2级或3级锁。
方法表->写锁
当锁在这一点上方时,Julia代码不能被调用。
orc::ThreadSafeContext(TSCtx)锁在锁层次结构中占有特殊的位置。 它们用于保护LLVM的全局非线程安全状态,但可以有任意数量的它们。 默认情况下,与层次结构的其余部分相比,所有这些锁都可以被视为5级锁。 您应该仅从TSCtx JIT池接收TSCtx,并且必须在该tsctx返回池之前解除该tsctx上的所有锁定。 如果需要在同一时间获取多个TSCtx锁(由于递归编译),则应按照从池中获取TSCtx锁的相同顺序获取它们。
以下是5级锁定:
JuliaOJIT::EmissionMutex
下面是一个6级锁,可以递归地只接收较低级别的锁。
科德根
jl_modules_mutex
下一个锁几乎是根锁(倒数第二级),这意味着在尝试获取它时只能持有根锁。
n.打字,打字
此选项可能是最困难的选项之一,因为类型推断可以从许多点调用。
目前,此锁与代码生成锁相结合,因为它们以递归方式相互调用。
下一个锁同步I/O操作。 请记住,在保持上面列出的任何其他锁的同时执行任何I/O操作(例如,输出警告消息或调试信息)都可能导致危险且难以检测的死锁。 要非常小心!
伊奥洛克
单独的ThreadSynchronizers锁
您可以在释放iolock锁后继续持有它们或在没有它的情况下接收它们,但要非常小心,不要试图在持有这些锁时获得iolock锁。
阻止Libdl。[医]拉齐奥图书馆
下一个锁是根锁,这意味着在尝试获取它时不能持有其他锁。
最高层
当尝试执行顶级操作(例如,创建新类型或定义新方法)时,应持有此锁:尝试在中间函数中获取此锁将导致死锁条件。
此外,还不清楚是否可以安全地与任意顶级表达式并行执行任何代码。 因此,可能需要所有线程首先到达安全点。
通用全局数据结构
每个这样的数据结构都需要锁,因为它们共享一个可变的全局状态。 下面是上述锁定优先级列表的反向列表。 它不包括1st级别的最终资源,因为它们太简单了。
MethodTable modifications(def,cache):MethodTable->writelock
类型声明:顶级锁
类型的应用:阻塞typecache
全局变量表:模块->锁
模块序列化器:顶级锁
JIT和类型推断:阻塞代码生成
MethodInstance/CodeInstance的更新:Method->writelock,阻止代码生成
这些是在创建时设置的,并且是不可变的。: 眼镜 sparam_vals def 业主
这些是使用`jl_type_infer’设置的(同时持有代码生成锁): 缓存 rettype **推断*可接受年龄
'InInference’标志: 优化,以便在`jl_type_infer`函数已经运行时快速防止重复 实际状态("推断"安装,然后是"fptr")由代码生成锁保护
函数指针: **在代码生成锁被保持的情况下,执行一次从"NULL"到值的转换。
代码生成器缓存(
functionObjectsDecls’的内容): 可以跳转几次,但只有在代码生成锁被持有时才会跳转 您可以使用其旧版本或阻止新版本,因此竞赛并不危险,除非代码引用方法实例中的其他数据(例如,`rettype
)并假设它们是一致的,除非它持有代码生成锁。
LLVMContext:阻塞代码生成
方法:方法->writelock
-
根数组(序列化器和代码生成)
-
TFUNC挑战/专业化/修改