From d7e262cdf7782dc2792c1792fcebbaa91d7cabf9 Mon Sep 17 00:00:00 2001 From: bicijinlian Date: Wed, 5 Apr 2023 11:14:13 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Jupyter笔记.2.4.线程本地存储.ipynb | 77 +++--------- Docs/Jupyter笔记.2.5.原子操作.ipynb | 113 ++++++++++-------- 2 files changed, 81 insertions(+), 109 deletions(-) diff --git a/Docs/Jupyter笔记.2.4.线程本地存储.ipynb b/Docs/Jupyter笔记.2.4.线程本地存储.ipynb index 231b7ba..b15973c 100644 --- a/Docs/Jupyter笔记.2.4.线程本地存储.ipynb +++ b/Docs/Jupyter笔记.2.4.线程本地存储.ipynb @@ -105,7 +105,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -114,17 +114,7 @@ "kernelName": "csharp" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "线程[020] 执行了 100 次,结束时 TotalLoopNumber = 196\n", - "线程[017] 执行了 100 次,结束时 TotalLoopNumber = 196\n", - "主(执行)线程[007] 结束时,TotalLoopNumber = 196\n" - ] - } - ], + "outputs": [], "source": [ "//非线程安全类\n", "public class Computer\n", @@ -201,7 +191,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -210,17 +200,7 @@ "kernelName": "csharp" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "线程[017] 执行了 100 次,结束时 TotalLoopNumber = 100\n", - "线程[042] 执行了 100 次,结束时 TotalLoopNumber = 100\n", - "主(执行)线程[007] 结束时,TotalLoopNumber = 0\n" - ] - } - ], + "outputs": [], "source": [ "//使用 ThreadStatic 特性,实现线程本地存储\n", "public class Computer2\n", @@ -274,19 +254,16 @@ }, { "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "线程[030] 执行了 100 次,结束时 数据槽 = 100\n", - "线程[029] 执行了 100 次,结束时 数据槽 = 100\n", - "因为在线程中使用了数据槽,主线程没有设置过,为Null\n" - ] + "execution_count": null, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" } - ], + }, + "outputs": [], "source": [ "//使用 数据槽,实现线程本地存储\n", "public class Computer3\n", @@ -350,7 +327,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -359,17 +336,7 @@ "kernelName": "csharp" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "线程[010] 执行了 100 次,结束时 TotalLoopNumber = 100\n", - "线程[045] 执行了 100 次,结束时 TotalLoopNumber = 100\n", - "主(执行)线程[007] 结束时,TotalLoopNumber = 0\n" - ] - } - ], + "outputs": [], "source": [ "//使用 ThreadLocal 泛型类,实现线程本地存储\n", "public class Computer4\n", @@ -431,7 +398,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -440,17 +407,7 @@ "kernelName": "csharp" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "线程[046] 执行了 100 次,结束时 TotalLoopNumber = 100\n", - "线程[043] 执行了 100 次,结束时 TotalLoopNumber = 100\n", - "主(执行)线程[007] 结束时,TotalLoopNumber = 0\n" - ] - } - ], + "outputs": [], "source": [ "//使用 AsynLocal 泛型类,针对异步方法实现线程的本地存储\n", "public class Computer5\n", diff --git a/Docs/Jupyter笔记.2.5.原子操作.ipynb b/Docs/Jupyter笔记.2.5.原子操作.ipynb index 15646c8..160fe8c 100644 --- a/Docs/Jupyter笔记.2.5.原子操作.ipynb +++ b/Docs/Jupyter笔记.2.5.原子操作.ipynb @@ -25,14 +25,6 @@ "+ 综合使用" ] }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 全局设置,语言设置、Nuget包引用、空间引用等" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -49,6 +41,9 @@ }, "polyglot_notebook": { "kernelName": "csharp" + }, + "vscode": { + "languageId": "polyglot-notebook" } }, "outputs": [], @@ -104,6 +99,31 @@ "}" ] }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## .Net中的原子操作类" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + ".Net中, System.Threading.Interlocked 类提供了用于执行原子操作的函数,这些函数接收引用参数(ref),也就是变量内存地址,然后针对该内存地址的值执行原子操作。" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Increment\n", + "Interlocked.Increment 函数执行的原子操作属于 “获取-添加”分类,执行后变量的值增加1,返回的值是增加后的值,即增加前的值加1" + ] + }, { "cell_type": "code", "execution_count": null, @@ -113,59 +133,50 @@ }, "polyglot_notebook": { "kernelName": "csharp" + }, + "vscode": { + "languageId": "polyglot-notebook" } }, "outputs": [], "source": [ - "//全局设置\n", - "#!csharp\n", - "using System.Threading;\n", - "using System.Threading.Channels;\n", - "using System.Threading.Tasks;\n", - "\n", - "//全局变量\n", - "var noteBookThreadDesc = \"NoteBook线程\";\n", - "\n", - "//全局方法\n", - "//显示线程信息\n", - "public void ShowThreadInfo(Thread showThread=null, string describe = null)\n", + "//计数器类\n", + "public class Counter\n", "{\n", - " if(showThread == null)\n", - " {\n", - " showThread = Thread.CurrentThread;\n", - " }\n", + " //总次数\n", + " public static int TotalNumber = 0;\n", + " \n", + " //方法循环次数\n", + " public static readonly int LoopNumber = 100;\n", "\n", - " if(string.IsNullOrWhiteSpace(describe))\n", + " //执行\n", + " public static void Execute()\n", " {\n", - " describe = showThread.Name == null ? \"无名\" : showThread.Name;\n", + " for (int i = 1; i <= LoopNumber; i++)\n", + " {\n", + " //原子操作\n", + " System.Threading.Interlocked.Increment(ref TotalNumber);\n", + " }\n", + " Console.WriteLine($\"线程[{Thread.CurrentThread.ManagedThreadId.ToString(\"000\")}] 执行了累加 {LoopNumber} 次,结束时 TotalNumber = {TotalNumber}\");\n", " }\n", - "\n", - " Console.WriteLine($\"{describe}线程ID:{showThread.ManagedThreadId} \");\n", - " Console.WriteLine($\"{describe}线程名:{showThread.Name} \");\n", - " Console.WriteLine($\"{describe}线程状态:{showThread.ThreadState} \");\n", - " Console.WriteLine($\"{describe}线程模式:{showThread.GetApartmentState()} \");\n", - " Console.WriteLine($\"{describe}激活:{(showThread.IsAlive ? \"活动\" : \"非活动\")} \");\n", - " Console.WriteLine($\"{describe}线程池线程:{(showThread.IsThreadPoolThread ? \"是的\" : \"否\")} \");\n", - " Console.WriteLine($\"{describe}后台线:{(showThread.IsBackground ? \"是的\" : \"不是\")} \");\n", - " Console.WriteLine($\"{describe}区域:{showThread.CurrentCulture}\");\n", - " Console.WriteLine($\"{describe}UI区域:{showThread.CurrentUICulture}\");\n", - " Console.WriteLine($\"{describe}优先级:{showThread.Priority}\");\n", "}\n", "\n", - "//显示线程状态\n", - "public void ShowThreadState(Thread showThread=null, string describe = null)\n", + "//使用域隔离和代码折叠\n", "{\n", - " if(showThread == null)\n", + " var threads = new List()\n", " {\n", - " showThread = Thread.CurrentThread;\n", - " }\n", + " new Thread(Counter.Execute){Name=\"thread_a\"},\n", + " new Thread(Counter.Execute){Name=\"thread_b\"}\n", + " };\n", "\n", - " if(string.IsNullOrWhiteSpace(describe))\n", - " {\n", - " describe = showThread.Name == null ? \"无名\" : showThread.Name;\n", - " }\n", - " Console.WriteLine($\"{describe}线程状态:{showThread.ThreadState} \");\n", - "}" + " threads.ForEach(t => t.Start());\n", + " threads.ForEach(t => t.Join());\n", + "\n", + " //主线程信息\n", + " Console.WriteLine($\"主(执行)线程[{Thread.CurrentThread.ManagedThreadId.ToString(\"000\")}] 结束时,TotalLoopNumber = {Counter.TotalNumber}\");\n", + "}\n", + "\n", + "//原子操作,多线程下多次执行结果相同" ] } ], @@ -176,7 +187,11 @@ "name": ".net-csharp" }, "language_info": { - "name": "polyglot-notebook" + "file_extension": ".cs", + "mimetype": "text/x-csharp", + "name": "C#", + "pygments_lexer": "csharp", + "version": "11.0" }, "polyglot_notebook": { "kernelInfo": {