当前位置: 首页 > news >正文

go中runtime包里面的mutex是什么?runtime.mutex解析

其实在看go源码的时候,发现除了sync包里有个mutex以外,runtime包里也有一个mutex,这个mutex在runtime很多地方都在用。

 这个runtime包里面的mutex的结构如下:

目录: /runtime/runtime2.go

代码:

type mutex struct {lockRankStructkey uintptr
}

可以看到他有两个成员,一个是lockRankStruct,一个是key。

先看下lockRankStruct

lockRankStruct 这个结构体是个空的结构体,在网上有大佬这样描述:

lockRankStruct提供了一种运行时的静态锁排名的机制。静态锁排名会建立文件化的锁之间的总排序顺序,如果违反总的排序,则会报错。只要锁排序是按照文档设计的顺序,锁排序死锁就不会发生。如果要做Go运行时使用这个机制,你需要设置GOEXPERIMENT=staticlockranking。 默认未开启,此时lockRanStruct是一个空结构体。lockWithRank()等效于lock()

啥意思啊?按照文档设计顺序,文档是啥,文档顺序是啥?

其实这里是一种非常机翻的说法,他其实说的是在go的配置中启动GOEXPERIMENT=staticlockranking,就会按照一定的顺序检查锁,如果锁不是按照这个顺序进行了,就会出现死锁的情况,那么就会抛出throw(在runtime包内部很多错误是throw,不是panic,throw方法并没有暴露给用户使用,用户只能用recover接panic,也就说用户无法处理throw错误,项目会直接崩掉)

那这个顺序是哪来的?

这个顺序其实是已经规定好的,当然是go语言的开发人员提交的,提交这个changes的地址是https://go-review.googlesource.com/c/go/+/207619

他这个顺序其实是一个map,一个已经规定好的map,lockPartialOrder,位置是runtime包中的lockrank.go

var lockPartialOrder [][]lockRank = [][]lockRank{lockRankSysmon:         {},lockRankScavenge:       {lockRankSysmon},lockRankForcegc:        {lockRankSysmon},lockRankDefer:          {},lockRankSweepWaiters:   {},lockRankAssistQueue:    {},lockRankSweep:          {},lockRankPollDesc:       {},lockRankCpuprof:        {},lockRankSched:          {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof},lockRankAllg:           {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched},lockRankAllp:           {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched},lockRankTimers:         {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllp, lockRankTimers},lockRankNetpollInit:    {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllp, lockRankTimers},lockRankHchan:          {lockRankSysmon, lockRankScavenge, lockRankSweep, lockRankHchan},lockRankNotifyList:     {},lockRankSudog:          {lockRankSysmon, lockRankScavenge, lockRankSweep, lockRankHchan, lockRankNotifyList},lockRankRwmutexW:       {},lockRankRwmutexR:       {lockRankSysmon, lockRankRwmutexW},lockRankRoot:           {},lockRankItab:           {},lockRankReflectOffs:    {lockRankItab},lockRankUserArenaState: {},lockRankTraceBuf:       {lockRankSysmon, lockRankScavenge},lockRankTraceStrings:   {lockRankSysmon, lockRankScavenge, lockRankTraceBuf},lockRankFin:            {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},lockRankGcBitsArenas:   {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},lockRankMheapSpecial:   {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},lockRankMspanSpecial:   {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},lockRankSpanSetSpine:   {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},lockRankProfInsert:     {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},lockRankProfBlock:      {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},lockRankProfMemActive:  {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},lockRankProfMemFuture:  {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankProfMemActive},lockRankGscan:          {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture},lockRankStackpool:      {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},lockRankStackLarge:     {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},lockRankHchanLeaf:      {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankHchanLeaf},lockRankWbufSpans:      {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},lockRankMheap:          {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans},lockRankGlobalAlloc:    {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMheapSpecial, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap},lockRankTrace:          {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap},lockRankTraceStackTab:  {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap, lockRankTrace},lockRankPanic:          {},lockRankDeadlock:       {lockRankPanic, lockRankDeadlock},
}

其实这玩意称之为“文档”多少有点不太直观,但是你知道是什么意思就行,不必纠结这个命名,很多命名有一定的历史因素或者直译不够信雅达,追求这个考古结果太浪费时间

那这个顺序是怎么验证的?

其实验证这个顺序的方法也不复杂,就在runtime/lockrank_on.go文件里的checkRanks方法里

func checkRanks(gp *g, prevRank, rank lockRank) {rankOK := falseif rank < prevRank {// If rank < prevRank, then we definitely have a rank errorrankOK = false} else if rank == lockRankLeafRank {// If new lock is a leaf lock, then the preceding lock can// be anything except another leaf lock.rankOK = prevRank < lockRankLeafRank} else {// We've now verified the total lock ranking, but we// also enforce the partial ordering specified by// lockPartialOrder as well. Two locks with the same rank// can only be acquired at the same time if explicitly// listed in the lockPartialOrder table.list := lockPartialOrder[rank]for _, entry := range list {if entry == prevRank {rankOK = truebreak}}}if !rankOK {printlock()println(gp.m.procid, " ======")printHeldLocks(gp)throw("lock ordering problem")}
}

不知道这个有啥影响么?

没有,不开启GOEXPERIMENT=staticlockranking 都不用关心这个问题,不看源码甚至不知道这个玩意,不必太在意,看到了当个乐子就行


再看下key:

key的实现方式有两种

runtime/lock_futex.go 文件里的futex实现

//go:build dragonfly || freebsd || linux

主要是dragonfly,FreeBSD,linux 系统;

另一个就是 runtime/lock_sema.go 文件里的 sema实现

//go:build aix || darwin || netbsd || openbsd || plan9 || solaris || windows

主要是 aix , darwin , netbsd , openbsd , plan9 , solaris , windows系统

但是实现起来也是大差不差的。

以linux的为例,毕竟日常开发还是linux的项目比较多。

首先,锁的状态有三种

const (mutex_unlocked = 0mutex_locked   = 1mutex_sleeping = 2
  • mutex_unlocked = 没有锁   
  • mutex_locked = 锁了 
  • mutex_sleeping = 表示有线程调用futexsleep阻塞了

然后看lock方法,这个是获取锁的方法

func lock2(l *mutex) {// 获取当前运行该方法的协程Ggp := getg()// 锁都是负数了,出问题了,报错,throw扔出去if gp.m.locks < 0 {throw("runtime·lock: lock count")}// 当前协程G绑定的M上的lock计数+1,不懂的去看GMP结构gp.m.locks++// 资源比较空闲时候,第一次请求锁就成功了,直接返回,表示获取锁成功// Xchg直接交换值,没有CAS操作,Xchg比较简单,理论上更快,Cas还要做值对比,Xchg更适合去抢锁v := atomic.Xchg(key32(&l.key), mutex_locked)if v == mutex_unlocked {return}// 大部分情况下,你获取是失败的,毕竟加锁的场景就是高并发引起的冲突,不然你加个毛的锁// 当v是mutex_unlock和mutex_sleeping的时候,也就说加锁没有成功// 修改名称把状态改成wait——等待wait := v// 自旋次数,如果ncpu也就是cpu核心数大于1,说明是多核cpu,那么就自旋等待下,active_spin实际上是4,那就是自旋4次,至于为什么是4,我没深究spin := 0if ncpu > 1 {// spin是spinning的意思“旋转的”,你打红警的时候盖特机炮的台词就有spinspin = active_spin}for {// 尝试获取锁for i := 0; i < spin; i++ {for l.key == mutex_unlocked {// Cas操作,获取锁。这里的wait的值第一次是上面传入的,第二次则是从for循环末尾拿到的if atomic.Cas(key32(&l.key), mutex_unlocked, wait) {return}}// 这个方法其实是底层调用了CPU的PAUSE指令,意在优化自旋等待的效率,主要是针对赛扬和志强cpu的procyield(active_spin_cnt)}// passive_spin = 1,passive -- 被动的,被动自旋,就是说上面4次自旋都没拿到,再给你一次机会,让你再获取一次锁,所以整个获取锁的自旋次数是 4 + 1for i := 0; i < passive_spin; i++ {for l.key == mutex_unlocked {// 同样的CAS操作获取锁if atomic.Cas(key32(&l.key), mutex_unlocked, wait) {return}}// 让出cpuosyield()}// 切换锁的状态为sleeping,xchg返回原来的值v = atomic.Xchg(key32(&l.key), mutex_sleeping)// 如果原来的值是mutex_unlocked,也就说无锁,那么mutex_sleeping 本身就算拿到锁了if v == mutex_unlocked {return}// 重新设定wait值为mutex_sleeping为下次循环做准备wait = mutex_sleeping// futexsleep调用futex函数进入睡眠。futexsleep(key32(&l.key), mutex_sleeping, -1)}
}

最后看unlock方法,这个是解锁的方法

func unlock2(l *mutex) {// 设置 l.key = mutex_unlocked。v是旧值v := atomic.Xchg(key32(&l.key), mutex_unlocked)// 如果已经是unlocked 你还执行解锁,那么就抛出throw异常if v == mutex_unlocked {throw("unlock of unlocked lock")}// 如果旧状态是sleeping,说明已经有其他协程在等待这个锁,处于sleep状态,这时候解锁的时候,要把那个sleep的协程唤醒if v == mutex_sleeping {// 执行futexwakeupfutexwakeup(key32(&l.key), 1)}// 获取当前的goroutinegp := getg()// 当前g所属的M的锁计数器减一gp.m.locks--if gp.m.locks < 0 {throw("runtime·unlock: lock count")}// m所有的锁已经释放且g本身的preempt位在解锁(unlock)之前就被被标记为true,说明该g可以被抢占了if gp.m.locks == 0 && gp.preempt { // 既然需要被抢占,那么就要设置stackguard0位置为stackPreempt,手动标记为需要检查栈溢出,当调度器检查到栈溢出的时候会根据Goroutine的标记进行相应处理,这里就是减产preempt并执行抢占gp.stackguard0 = stackPreempt}
}

大致就是这样了

相关文章:

go中runtime包里面的mutex是什么?runtime.mutex解析

其实在看go源码的时候&#xff0c;发现除了sync包里有个mutex以外&#xff0c;runtime包里也有一个mutex&#xff0c;这个mutex在runtime很多地方都在用。 这个runtime包里面的mutex的结构如下&#xff1a; 目录: /runtime/runtime2.go 代码&#xff1a; type mutex struct …...

VScode 调试python程序,debug状态闪断问题的解决方法

0. Few words 之前一直在VSCode中debug C和Python的程序没出过闪断的问题&#xff0c;但是最近在另一台电脑上debug&#xff0c;同样的方法&#xff0c;设置launch.json和CMakeList加debug状态等等操作&#xff0c;如我另一篇blog写的一样&#xff0c;可以点这里查看。 但是&a…...

飞桨中的李宏毅课程中的第一个项目——PM2.5的预测

所谓的激活函数&#xff0c;就是李宏毅老师讲到的sigmoid函数 和 hard sigmoid函数 &#xff0c;ReLU函数那些 现在一点点慢慢探索&#xff0c;会成为日后想都做不到的经历&#xff0c;当你啥也不会的时候&#xff0c;才是慢慢享受探索的过程。 有一说一&#xff0c;用chatGP…...

Qt---对话框 事件处理 如何发布自己写的软件

目录 一、对话框 1.1 消息对话框&#xff08;QMessageBox&#xff09; 1> 消息对话框提供了一个模态的对话框&#xff0c;用来提示用户信息&#xff0c;或者询问用户问题并得到回答 2> 基于属性版本的API 3> 基于静态成员函数版本 4> 对话框案例 1、ui界面 …...

【C++】C++ 引用详解 ⑩ ( 常量引用案例 )

文章目录 一、常量引用语法1、语法简介2、常引用语法示例 二、常量引用语法1、int 类型常量引用示例2、结构体类型常量引用示例 在 C 语言中 , 常量引用 是 引用类型 的一种 ; 借助 常量引用 , 可以将一个变量引用 作为实参 传递给一个函数形参 , 同时保证该值不会在函数内部被…...

React原理 - React Reconciliation-下

目录 Fiber Reconciler 【react v16.13.1】 React Fiber需要解决的问题 React Fiber的数据结构 时间分片 Fiber Reconciler 的调度 双缓冲 池概念 小节 练习 Fiber Reconciler 【react v16.13.1】 Fiber 协调 优化了栈协调的事务性弊端引起的卡顿 React Fiber需要解决…...

YOLOv8超参数调优教程! 使用Ray Tune进行高效的超参数调优!

原创文章为博主个人所有,未经授权不得转载、摘编、倒卖、洗稿或利用其它方式使用上述作品。违反上述声明者,本站将追求其相关法律责任。 这篇博文带大家玩点新的东西,也是一直以来困扰大家最大的问题—超参数调优! 之前的 YOLOv5 我使用遗传算法做过很多次调优,实验一跑就…...

JVM运行时数据区

文章目录 JVM内存结构图1、运行时数据区域JDK 1.7JDK 1.81. 线程栈&#xff08;虚拟机栈&#xff09;2. 本地方法栈3. 程序计数器4. 方法区&#xff08;元空间&#xff09;5. 堆6、运行时常量池&#xff08;Runtime Constant Pool&#xff09;7、直接内存&#xff08;Direct Me…...

第七章,相似矩阵及其应用,3-二次型、合同矩阵与合同变换

第七章&#xff0c;相似矩阵及其应用&#xff0c;3-二次型、合同矩阵与合同变换 二次型相关概念二次型二次型的标准形和规范形表示形式 合同矩阵与合同变换定义 合同合同矩阵的性质等价、相似、合同三种关系的对比等价相似合同 玩转线性代数(38)二次型概念、合同矩阵与合同变换…...

css学习7(盒子模型)

1、盒子模型图&#xff1a; Margin(外边距) - 清除边框外的区域&#xff0c;外边距是透明的。Border(边框) - 围绕在内边距和内容外的边框。Padding(内边距) - 清除内容周围的区域&#xff0c;内边距是透明的。Content(内容) - 盒子的内容&#xff0c;显示文本和图像。 <!DO…...

C++笔记之临时变量与临时对象与匿名对象

C笔记之临时变量与临时对象与匿名对象 code review! 文章目录 C笔记之临时变量与临时对象与匿名对象1.C中的临时变量指的是什么&#xff1f;2.C中的临时对象指的是什么&#xff1f;3.C中临时对象的作用是什么&#xff1f;什么时候要用到临时对象?4.给我列举具体的例子说明临…...

缓存技术(缓存穿透,缓存雪崩,缓存击穿)

大家好 , 我是苏麟 , 今天聊一聊缓存 . 这里需要一些Redis基础 (可以看相关文章等) 本文章资料来自于 : 黑马程序员 如果想要了解更详细的资料去黑马官网查看 前言:什么是缓存? 缓存,就是数据交换的 缓冲区 (称作Cache [ kʃ ] ),俗称的缓存就是缓冲区内的数据,是存贮数据的…...

实操教程 | 触发器实现 Apache DolphinScheduler 失败钉钉自动告警

作者 | sqlboy-yuzhenc 背景介绍 在实际应用中&#xff0c;我们经常需要将特定的任务通知给特定的人&#xff0c;虽然 Apache DolphinScheduler 在安全中心提供了告警组和告警实例&#xff0c;但是配置起来相对复杂&#xff0c;并且还需要在定时调度时指定告警组。通过这篇文…...

以“迅”防“汛”!5G视频快线筑牢防汛“安全堤”

近期&#xff0c;西安多地突发山洪泥石流灾害。防洪救灾刻不容缓&#xff0c;为进一步做好防汛工作&#xff0c;加强防洪调度监管&#xff0c;切实保障群众的生命财产安全&#xff0c;当地政府管理部门亟需拓展智能化技术&#xff0c;通过人防技防双保障提升防灾救灾应急处置能…...

jmeter 性能测试工具的使用(Web性能测试)

1、下载 该软件不用安装&#xff0c;直接解压打开即可使用。 2、使用 这里就在win下进行&#xff0c;图形界面较为方便   在目录apache-jmeter-2.13\bin 下可以见到一个jmeter.bat文件&#xff0c;双击此文件&#xff0c;即看到JMeter控制面板。主界面如下&#xff1a; 3、创…...

springboot整合第三方技术邮件系统

springboot整合第三方技术邮件系统&#xff0c;发邮件是java程序的基本操作&#xff0c;springboot整合javamail其实就是简化开发。不熟悉邮件的小伙伴可以先学习完javamail的基础操作&#xff0c;再来看这一部分内容才能感触到springboot整合javamail究竟简化了哪些操作。简化…...

Python入门学习——Day2-变量和数据类型

一、Python 变量 在Python中&#xff0c;变量用于保存数据&#xff0c;方便程序对数据的处理和操作。下面是关于Python变量的一些重要概念&#xff1a; 变量命名规则&#xff1a; 变量名由字母、数字和下划线组成。变量名可以以字母或下划线开头&#xff0c;但不能以数字开头…...

Graylog 更改显示的时区(Display timezone)

每个 Graylog 用户都可以配置他们的显示时区。 这会更改用于查看日志消息的时区&#xff0c;但不会更改日志消息的原始时区。 默认情况下&#xff0c;Graylog 显示 UTC 格式的所有时间戳&#xff08;也就是 0:00&#xff09;。就像是下面这样 非Admin账户要更改时区&#xff1…...

【网络安全防护】上海道宁与Bitdefender帮助您构建弹性网络并降低安全运营成本

在网络的世界中 风险变得更加常见与复杂 企业需要从网络安全转向网络弹性 复杂的网络攻击已非常普遍 在面临攻击时 企业如何保持业务连续性&#xff1f; Bitdefender GravityZone将 风险分析、安全加固、威胁预防 检测和响应功能相结合 帮助您构建弹性网络 并降低安全…...

文心一言 VS CHATGPT

由于近几天来&#xff0c;我的手机短信不断收到百度公司对于“文心一言”大模型的体验邀请&#xff08;真是不胜其烦&#xff09;&#xff01;&#xff01;所以我就抱着试试看的态度点开了文心一言的链接&#xff1a;文心一言 目前看来&#xff0c;有以下两点与chatgpt是有比较…...

2023-09-01力扣每日一题

链接&#xff1a; 2240. 买钢笔和铅笔的方案数 题意&#xff1a; 一共total元&#xff0c;两种笔分别cost1和cost2元&#xff0c;求能买的的笔的所有情况&#xff0c;不要求花光钱 解&#xff1a; 枚举其中一个数字就行 实际代码&#xff1a; #include<bits/stdc.h&g…...

【Python】从入门到上头— IO编程(8)

文章目录 一.IO编程是什么二.文件读写1.读取文件2.file-like Object二进制文件字符编码 3.写文件file对象的常用函数常见标识符 三.StringIO和BytesIO1.StringIO2.BytesIO 四.操作文件和目录五.序列化和反序列化1.pickle.dumps()2.pickle.loads()3.JSON 一.IO编程是什么 IO在计…...

R语言对综合社会调查GSS数据进行自举法bootstrap统计推断、假设检验、探索性数据分析可视化|数据分享...

全文链接&#xff1a;https://tecdat.cn/?p33514 综合社会调查&#xff08;GSS&#xff09;是由国家舆论研究中心开展的一项观察性研究。自 1972 年以来&#xff0c;GSS 一直通过收集当代社会的数据来监测社会学和态度趋势。其目的是解释态度、行为和属性的趋势和常量。从 197…...

LeetCode 刷题第四轮 Offer I + 类型题

目录 剑指 Offer 04. 二维数组中的查找 剑指 Offer 29. 顺时针打印矩阵 剑指 Offer 09. 用两个栈实现队列 剑指 Offer 30. 包含min函数的栈 剑指 Offer 10- I. 斐波那契数列 [类型&#xff1a;记忆优化 递归 / 动态规划] 剑指 Offer 10- II. 青蛙跳台阶问题 [类型&am…...

LabVIEW计算测量路径输出端随机变量的概率分布密度

LabVIEW计算测量路径输出端随机变量的概率分布密度 今天&#xff0c;开发算法和软件来解决计量综合的问题&#xff0c;即为特定问题寻找最佳测量算法。提出了算法支持&#xff0c;以便从计量上综合测量路径并确定所开发测量仪器的测量误差。测量路径由串联的几个块组成&#x…...

[C++ 网络协议] 多进程服务器端

具有代表性的并发服务器端实现模型和方法&#xff1a; 多进程服务器&#xff1a;通过创建多个进程提供服务。✔ 多路复用服务器&#xff1a;通过捆绑并统一管理I/O对象提供服务。 多线程服务器&#xff1a;通过生成与客户端等量的线程提供服务。 目录 1. 进程的概念及应用 1.…...

李宏毅 2022机器学习 HW2 strong baseline 上分路线

strong baseline上分路线 baseline增加concat_nframes &#xff08;提升明显&#xff09;增加batchnormalization 和 dropout增加hidden layer宽度至512 &#xff08;提升明显&#xff09; 提交文件命名规则为 prediction_{concat_nframes}[{n_hidden_layers}{dropout}_bn].c…...

伦敦银交易时间怎么选择?

伦敦银和伦敦金都是全球性的交易品种&#xff0c;一般的现货贵金属交易平台&#xff0c;都可以同时经营这两个品种&#xff0c;而且它们的交易时间是一致的&#xff0c;以香港市场的平台为例&#xff0c;基本上交易时间都会从北京周一的早上7点&#xff0c;延续到周六凌晨5点左…...

解决FreeRTOS程序跑不起来,打印调试却提示“Error:..\FreeRTOS\port\RVDS\ARM_CM3\port.c,244“的方法

前言 今天来分享一个不会造成程序编译报错&#xff0c;但会使程序一直跑不起来&#xff0c;并且通过调试会发现有输出错误提示的错误例子分析&#xff0c;话不多说&#xff0c;我们就直接开始分析~ 首先&#xff0c;我们说过这个例子在编译时候没有明示的错误提示&#xff0c…...

Python序列类型

序列&#xff08;Sequence&#xff09;是有顺序的数据列&#xff0c;Python 有三种基本序列类型&#xff1a;list, tuple 和 range 对象&#xff0c;序列&#xff08;Sequence&#xff09;是有顺序的数据列&#xff0c;二进制数据&#xff08;bytes&#xff09; 和 文本字符串&…...