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

株洲网站建设方案wordpress配置cdn缓存规则

株洲网站建设方案,wordpress配置cdn缓存规则,外贸网站模板大全,wordpress wp_set_auth_cookie一#xff1a;背景 1. 讲故事 这个问题的由来是在.NET高级调试训练营第十期分享ThreadStatic底层玩法的时候#xff0c;有朋友提出了AsyncLocal是如何实现的#xff0c;虽然做了口头上的表述#xff0c;但总还是会不具体#xff0c;所以觉得有必要用文字图表的方式来系统…一背景 1. 讲故事 这个问题的由来是在.NET高级调试训练营第十期分享ThreadStatic底层玩法的时候有朋友提出了AsyncLocal是如何实现的虽然做了口头上的表述但总还是会不具体所以觉得有必要用文字图表的方式来系统的说一下这个问题。 二AsyncLocal 线程间传值 1. 线程间传值途径 在 C# 编程中实现多线程以及线程切换的方式大概如下三种 ThreadTaskawaitasync 这三种场景下的线程间传值有各自的实现方式由于篇幅限制先从 Thread 开始聊吧。本质上来说 AsyncLocal 是一个纯托管的C#玩法和 coreclrWindows 没有任何关系。 2. Thread 小例子 为了方便讲述先来一个例子看下如何在新Thread线程中提取 _asyncLocal 中的值参考代码如下 internal class Program{static AsyncLocalint _asyncLocal new AsyncLocalint();static void Main(string[] args){_asyncLocal.Value 10;var t new Thread(() {Console.WriteLine($Tid{Thread.CurrentThread.ManagedThreadId}, AsyncLocal value: {_asyncLocal.Value},);Debugger.Break();});t.Start();Console.ReadLine();}} 从截图看 tid7 线程果然拿到了 主线程设置的 10 哈哈是不是充满了好奇心接下来逐一分析下吧。 3. 流转分析 首先观察下 _asyncLocal.Value 10 在源码层做了什么参考代码如下 public T Value{set{ExecutionContext.SetLocalValue(this, value, m_valueChangedHandler ! null);}}internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications){ExecutionContext executionContext Thread.CurrentThread._executionContext;Thread.CurrentThread._executionContext new ExecutionContext(asyncLocalValueMap, array, flag2));} 从源码中可以看到这个 10 最终封印在 Thread.CurrentThread._executionContext 字段中接下来就是核心问题了它是如何被送到新线程中的呢 其实仔细想一想要让我实现的话我肯定这么实现。 将主线程的 _executionContext 字段赋值给新线程 t._executionContext 字段。 将 var t new Thread() 中的t作为参数传递给 win32 的 CreateThread 函数这样在新线程中就可以提取 到 t 了然后执行 t 的callback。 这么说大家可能有点抽象我就直接画下C#是怎么流转的图吧 有了这张图之后接下来的问题就是验证了首先看一下 copy 操作在哪里 可以观察下 Start 源码。 private void Start(bool captureContext){StartHelper startHelper _startHelper;if (startHelper ! null){startHelper._startArg null;startHelper._executionContext (captureContext ? System.Threading.ExecutionContext.Capture() : null);}StartCore();}public static ExecutionContext? Capture(){ExecutionContext executionContext Thread.CurrentThread._executionContext;return executionContext;} 从源码中可以看到将主线程的 _executionContext 字段给了新线程t下的startHelper._executionContext 。 接下来我们观察下在创建 OS 线程的时候是不是将 Thread 作为参数传过去了如果传过去了那就可以直接在新线程中拿到 Thread._startHelper._executionContext 字段验证起来也很简单在win32 的 ntdll!NtCreateThreadEx 上下一个断点即可。 0:000 bp ntdll!NtCreateThreadEx 0:000 g Breakpoint 1 hit ntdll!NtCreateThreadEx: 00007ff90fe8e8c0 4c8bd1 mov r10,rcx 0:000 r rax00007ff8b4a529d0 rbx0000000000000000 rcx0000008471b7df28 rdx00000000001fffff rsi0000027f2ca25b01 rdi0000027f2ca25b60 rip00007ff90fe8e8c0 rsp0000008471b7de68 rbp00007ff8b4a529d0r80000000000000000 r9ffffffffffffffff r100000027f2c8a0000 r110000008471b7de40 r120000008471b7e890 r130000008471b7e4f8 r14ffffffffffffffff r150000000000010000 iopl0 nv up ei pl nz na po nc cs0033 ss002b ds002b es002b fs0053 gs002b efl00000206 ntdll!NtCreateThreadEx: 00007ff90fe8e8c0 4c8bd1 mov r10,rcx 0:000 !t ThreadCount: 4 UnstartedThread: 1 BackgroundThread: 2 PendingThread: 0 DeadThread: 0 Hosted Runtime: noLock DBG ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception0 1 2cd8 0000027F2C9E6610 2a020 Preemptive 0000027F2E5DB438:0000027F2E5DB4A0 0000027f2c9dd670 -00001 MTA 6 2 2b24 0000027F2CA121E0 21220 Preemptive 0000000000000000:0000000000000000 0000027f2c9dd670 -00001 Ukn (Finalizer) 7 3 2658 0000027F4EAA0AE0 2b220 Preemptive 0000000000000000:0000000000000000 0000027f2c9dd670 -00001 MTA XXXX 4 0 0000027F2CA25B60 9400 Preemptive 0000000000000000:0000000000000000 0000027f2c9dd670 -00001 Ukn 从输出中可以看到 NtCreateThreadEx 方法的第二个参数即 rdi0000027f2ca25b60 就是我们的托管线程如果你不相信的话可以再用 windbg 找到它的托管线程信息输出如下 0:000 dt coreclr!Thread 0000027F2CA25B60 -y m_ExposedObject0x1c8 m_ExposedObject : 0x0000027f2c8f11d0 OBJECTHANDLE__0:000 !do poi(0x0000027f2c8f11d0) Name: System.Threading.Thread MethodTable: 00007ff855090d78 EEClass: 00007ff85506a700 Tracked Type: false Size: 72(0x48) bytes File: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.25\System.Private.CoreLib.dll Fields:MT Field Offset Type VT Attr Value Name 00007ff8550c76d8 4000b35 8 ....ExecutionContext 0 instance 0000000000000000 _executionContext 0000000000000000 4000b36 10 ...ronizationContext 0 instance 0000000000000000 _synchronizationContext 00007ff85508d708 4000b37 18 System.String 0 instance 0000000000000000 _name 00007ff8550cb9d0 4000b38 20 ...hreadStartHelper 0 instance 0000027f2e5db3b0 _startHelper ... 有些朋友可能要说你现在的 _executionContext 字段是保留在 _startHelper 类里并没有赋值到Thread._executionContext字段呀那这一块在哪里实现的呢从上图可以看到其实是在新线程的执行函数上在托管函数执行之前会将 _startHelper._executionContext 赋值给 Thread._executionContext , 让 windbg 继续执行输出如下 0:009 k# Child-SP RetAddr Call Site 00 00000084728ff778 00007ff8b4c23d19 KERNELBASE!wil::details::DebugBreak0x2 01 00000084728ff780 00007ff8b43ba7ea coreclr!DebugDebugger::Break0x149 [D:\a\_work\1\s\src\coreclr\vm\debugdebugger.cpp 148] 02 00000084728ff900 00007ff854ff56e3 System_Private_CoreLib!System.Diagnostics.Debugger.Break0xa [/_/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs 18] 03 00000084728ff930 00007ff8b42b4259 ConsoleApp9!ConsoleApp9.Program.c.Mainb__1_00x113 04 00000084728ff9c0 00007ff8b42bddd9 System_Private_CoreLib!System.Threading.Thread.StartHelper.Callback0x39 [/_/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs 42] 05 00000084728ffa00 00007ff8b42b2f4a System_Private_CoreLib!System.Threading.ExecutionContext.RunInternal0x69 [/_/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs 183] 06 00000084728ffa70 00007ff8b4b7ba53 System_Private_CoreLib!System.Threading.Thread.StartCallback0x8a [/_/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs 105] 07 00000084728ffab0 00007ff8b4a763dc coreclr!CallDescrWorkerInternal0x83 08 00000084728ffaf0 00007ff8b4b5e713 coreclr!DispatchCallSimple0x80 [D:\a\_work\1\s\src\coreclr\vm\callhelpers.cpp 220] 09 00000084728ffb80 00007ff8b4a52d25 coreclr!ThreadNative::KickOffThread_Worker0x63 [D:\a\_work\1\s\src\coreclr\vm\comsynchronizable.cpp 158] ... 0d (Inline Function) ---------------- coreclr!ManagedThreadBase_FullTransition0x2d [D:\a\_work\1\s\src\coreclr\vm\threads.cpp 7569] 0e (Inline Function) ---------------- coreclr!ManagedThreadBase::KickOff0x2d [D:\a\_work\1\s\src\coreclr\vm\threads.cpp 7604] 0f 00000084728ffd60 00007ff90e777614 coreclr!ThreadNative::KickOffThread0x79 [D:\a\_work\1\s\src\coreclr\vm\comsynchronizable.cpp 230] 10 00000084728ffdc0 00007ff90fe426a1 KERNEL32!BaseThreadInitThunk0x14 11 00000084728ffdf0 0000000000000000 ntdll!RtlUserThreadStart0x21 ... 在上面的回调函数中看的非常清楚在执行托管函数 Mainb__1_0 之前执行了一个 ExecutionContext.RunInternal 函数对就是它来实现的参考代码如下 private sealed class StartHelper{internal void Run(){System.Threading.ExecutionContext.RunInternal(_executionContext, s_threadStartContextCallback, this);}}internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, object state){Thread currentThread Thread.CurrentThread;RestoreChangedContextToThread(currentThread, executionContext, executionContext3);}internal static void RestoreChangedContextToThread(Thread currentThread, ExecutionContext contextToRestore, ExecutionContext currentContext){currentThread._executionContext contextToRestore;} 既然将 StartHelper.executionContext 塞到了 currentThread._executionContext 中在 Mainb__1_0 方法中自然就能通过 _asyncLocal.Value 提取了。 三总结 说了这么多其实精妙之处在于创建OS线程的时候会把C# Thread实例(coreclr对应线程) 作为参数传递给新线程即下面方法签名中的 lpParameter 参数新线程拿到了Thread实例自然就能获取到被调用线程赋值的 Thread._executionContext 字段所以这是完完全全的C#层面玩法希望能给后来者解惑吧 HANDLE CreateThread([in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,[in] SIZE_T dwStackSize,[in] LPTHREAD_START_ROUTINE lpStartAddress,[in, optional] __drv_aliasesMem LPVOID lpParameter,[in] DWORD dwCreationFlags,[out, optional] LPDWORD lpThreadId );
http://www.zqtcl.cn/news/709037/

相关文章:

  • 为什么邮箱突然进不去了总提示正在进入不安全网站wordpress需注册访问
  • 建网站哪家最好山东泰安房价
  • wordpress4.9+多站点网络推广公司联系昔年下拉
  • 西安seo网站关键词优化罗田县建设局网站
  • 北京网站建设 shwllnmp新手 wordpress
  • 优化网站结构一般包括如何进行网络营销风险控制
  • 怎样查看网站是用什么做的郫都区规划建设局网站
  • 新乡营销型网站建设制作网站设计的总结
  • 做网站的免费空间微信crm管理系统
  • 网站开发方向 英语翻译护肤品网页设计图片
  • 南昌做兼职的网站佛山网站建设公司排名
  • 购物网站建设推进表国外设计素材网站
  • 广州网站建设推广公司有哪些有一个网站专门做民宿
  • 安徽省建设干部网站淘客网站超级搜怎么做
  • 网站地图提交地址网站地图可以自己做么
  • 电子商务网站建设与推广wordpress手机大标题
  • 网站页面上的下载功能怎么做ps扩展插件网站
  • 打开网站出现directory今天时政新闻热点是什么
  • 高校校园网站建设与运行网站规划教学设计
  • 包头手机网站制作seo推广手段
  • 汕头网站推广seo品牌网站建设 app建设
  • 网站后台word编辑器如何申请一个网站 做视频
  • 源代码做网站网站编辑可以做运营吗
  • 小游戏网站模板无锡网站建设818gx
  • 娄底做网站陕西网站维护
  • 电子商务网站建设首要问题是佛山网站设计步骤
  • iphone网站哈尔滨做平台网站平台公司吗
  • 公司网站制作高端有什么网站可以做外贸出口信息
  • 旅游网站建设ppt自己动手制作网站
  • 做注册任务的网站有哪些seo搜索排名优化