[{"data":1,"prerenderedAt":326},["ShallowReactive",2],{"page-2":3},{"title":4,"articles":5,"hot_article":111,"month_arch":174,"total":322,"cover":323},"第2页 - 独孤影的博客",[6,19,30,39,50,60,71,81,91,101],{"id":7,"title":8,"uri":9,"author":10,"tags":11,"created_at":16,"view_count":17,"content":18},111,"gin.Context 异步调用踩坑","gin-context-gorountine","duguying",[12,13,14,15],"gin","context","异步","goroutine","2023-12-08 12:20:18",448,"\u003Cp>事情的背景是这样了，我在gin框架的action中有个异步调用逻辑，然后异步调用需要使用\u003Ccode class=\"inline-code\">context.Context\u003C\u002Fcode>接口作为参数传入，异步调用的模块中会从context中取request_id作为追踪追踪标记。于是我就直接讲*gin.Context作为参数传入了异步调用中。\u003C\u002Fp>\n\n\u003Cp>然后灾难就发生了，我日志记录中能查到当前请求的request_id，但是发现条数不对，异步请求中记录的日志条数有10条，我用request_id去搜索，只查到了4条，最后我只能添加另外标记，通过另外的标记查询到10条日志，让我奇怪的是，另外6条日志的request_id却不是当前请求的request_id。\u003C\u002Fp>\n\n\u003Cp>最后，我发现gin.Context专门有个Copy方法，是将context拷贝一份，我调用Copy拷贝一份context之后将拷贝的context传入异步调用，果然10条日志的request_id一致了。看来，从gin框架传入进来的context在不同的action中是复用的。然后在请求处理完毕之后，会给其他请求复用，这样传给异步调用模块的context中的request_id已经变了。\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>r.\u003Cspan style=\"color:#d2a8ff;font-weight:bold\">GET\u003C\u002Fspan>(\u003Cspan style=\"color:#a5d6ff\">&#34;\u002Fasync&#34;\u003C\u002Fspan>, \u003Cspan style=\"color:#ff7b72\">func\u003C\u002Fspan>(c \u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>gin.Context) {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\t\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F 需要搞一个副本\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\tcopyContext \u003Cspan style=\"color:#ff7b72;font-weight:bold\">:=\u003C\u002Fspan> c.\u003Cspan style=\"color:#d2a8ff;font-weight:bold\">Copy\u003C\u002Fspan>()\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\t\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F 异步处理\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\t\u003Cspan style=\"color:#ff7b72\">go\u003C\u002Fspan> \u003Cspan style=\"color:#ff7b72\">func\u003C\u002Fspan>() {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\t\ttime.\u003Cspan style=\"color:#d2a8ff;font-weight:bold\">Sleep\u003C\u002Fspan>(\u003Cspan style=\"color:#a5d6ff\">3\u003C\u002Fspan> \u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan> time.Second)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\t\tlog.\u003Cspan style=\"color:#d2a8ff;font-weight:bold\">Println\u003C\u002Fspan>(\u003Cspan style=\"color:#a5d6ff\">&#34;异步执行：&#34;\u003C\u002Fspan> \u003Cspan style=\"color:#ff7b72;font-weight:bold\">+\u003C\u002Fspan> copyContext.Request.URL.Path)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\t}()\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>})\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>这里必须要谨记，如果需要在action中异步调用并使用context传参，必须要将context.Copy()之后再传入。否则context就会被其他协程修改。\u003C\u002Fp>\n",{"id":20,"title":21,"uri":22,"author":10,"tags":23,"created_at":27,"view_count":28,"content":29},110,"Bazel对依赖库进行patch遇到的问题","the-problem-in-patch-deps-with-bazel",[24,25,26],"bazel","patch","依赖","2023-12-07 12:24:09",457,"\u003Cp>最近使用bazel需要对一个go第三方依赖进行patch，这个依赖是gorm\u002Fv1，原作者对v1已经放弃了，我们项目中使用了v1，但是因为v1到v2是不兼容的升级，所以我们项目中无法升级。针对v1的优化和bug修复，就只能使用patch的方式进行了。\u003C\u002Fp>\n\n\u003Cp>第一步将\u003Ccode class=\"inline-code\">github.com\u002Fjinzhu\u002Fgorm\u003C\u002Fcode>克隆下来，check出最后一个版本v1.9.16，然后做修改。修改完毕之后，不要进行git提交，执行\u003Ccode class=\"inline-code\">git diff &gt;&gt; new1.patch\u003C\u002Fcode>将会生成这次变更的patch文件。\u003C\u002Fp>\n\n\u003Cp>将patch文件存储如下\u003Ccode class=\"inline-code\">0001-go-errors.patch\u003C\u002Fcode>\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>third_party_patches\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>└── com_github_jinzhu_gorm\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    ├── 0001-go-errors.patch\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    ├── 0002-fix-sqlite.patch\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    └── BUILD.bazel\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>其中，\u003Ccode class=\"inline-code\">BUILD.bazel\u003C\u002Fcode>空文件即可。另外\u003Ccode class=\"inline-code\">deps.bzl\u003C\u002Fcode>中的引用如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>go_repository(\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    name \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan> \u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">com_github_jinzhu_gorm\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    build_file_proto_mode \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan> \u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">disable\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    importpath \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan> \u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">github.com\u002Fjinzhu\u002Fgorm\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    patch_args \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan> [\u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">-p1\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>],\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    patches \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan> [\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>        \u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">\u002F\u002Fthird_party_patches\u002Fcom_github_jinzhu_gorm:0001-go-errors.patch\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>        \u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">\u002F\u002Fthird_party_patches\u002Fcom_github_jinzhu_gorm:0002-fix-sqlite.patch\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    ],\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    sum \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan> \u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">h1:+IyIjPEABKRpsu\u002FF8OvDPy9fyQlgsg2luMV2ZIH5i5o=\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    version \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan> \u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">v1.9.16\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>但是我编译的时候，却报错了\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>➜  code git:\u003Cspan style=\"color:#ff7b72;font-weight:bold\">(\u003C\u002Fspan>feature\u002Fmigrate-flow\u003Cspan style=\"color:#ff7b72;font-weight:bold\">)\u003C\u002Fspan> ✗ bazel build \u002F\u002F...\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>INFO: Analyzed \u003Cspan style=\"color:#a5d6ff\">74\u003C\u002Fspan> targets \u003Cspan style=\"color:#ff7b72;font-weight:bold\">(\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">3\u003C\u002Fspan> packages loaded, \u003Cspan style=\"color:#a5d6ff\">141\u003C\u002Fspan> targets configured\u003Cspan style=\"color:#ff7b72;font-weight:bold\">)\u003C\u002Fspan>.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>INFO: Found \u003Cspan style=\"color:#a5d6ff\">74\u003C\u002Fspan> targets...\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>ERROR: \u002Froot\u002F.cache\u002Fbazel\u002F_bazel_root\u002Faa05a35ce6b6cd2ce6b5a504fd9d9e22\u002Fexternal\u002Fcom_github_jinzhu_gorm\u002FBUILD.bazel:3:11: GoCompilePkg external\u002Fcom_github_jinzhu_gorm\u002Fgorm.a failed: \u003Cspan style=\"color:#ff7b72;font-weight:bold\">(\u003C\u002Fspan>Exit 1\u003Cspan style=\"color:#ff7b72;font-weight:bold\">)\u003C\u002Fspan>: builder failed: error executing command bazel-out\u002Fhost\u002Fbin\u002Fexternal\u002Fgo_sdk\u002Fbuilder compilepkg -sdk external\u002Fgo_sdk -installsuffix linux_amd64 -tags sqlite -src external\u002Fcom_github_jinzhu_gorm\u002Fassociation.go -src ... \u003Cspan style=\"color:#ff7b72;font-weight:bold\">(\u003C\u002Fspan>remaining \u003Cspan style=\"color:#a5d6ff\">71\u003C\u002Fspan> argument\u003Cspan style=\"color:#ff7b72;font-weight:bold\">(\u003C\u002Fspan>s\u003Cspan style=\"color:#ff7b72;font-weight:bold\">)\u003C\u002Fspan> skipped\u003Cspan style=\"color:#ff7b72;font-weight:bold\">)\u003C\u002Fspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>Use --sandbox_debug to see verbose messages from the sandbox\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>compilepkg: missing strict dependencies:\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>        \u002Froot\u002F.cache\u002Fbazel\u002F_bazel_root\u002Faa05a35ce6b6cd2ce6b5a504fd9d9e22\u002Fsandbox\u002Flinux-sandbox\u002F4877\u002Fexecroot\u002Fias-admin\u002Fexternal\u002Fcom_github_jinzhu_gorm\u002Fmain.go: import of \u003Cspan style=\"color:#a5d6ff\">&#34;github.com\u002Fgo-errors\u002Ferrors&#34;\u003C\u002Fspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>No dependencies were provided.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>Check that imports in Go sources match importpath attributes in deps.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>INFO: Elapsed time: 0.843s, Critical Path: 0.06s\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>INFO: \u003Cspan style=\"color:#a5d6ff\">4\u003C\u002Fspan> processes: \u003Cspan style=\"color:#a5d6ff\">4\u003C\u002Fspan> internal.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>FAILED: Build did NOT complete successfully\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>按照报错打开bazel cache路径，发现bazel为依赖生成的BUILD.bazel文件中，并没有添加我patch中引入的依赖。于是我将cache中的BUILD.bazel拷贝出来，手动加入依赖，然后git diff，得到BUILD.bazel的patch文件如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">diff --git a\u002FBUILD.bazel b\u002FBUILD.bazel\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">\u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">index 0849476..d26e9f7 100644\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">\u003C\u002Fspan>\u003Cspan style=\"color:#ffa198;background-color:#490202\">--- a\u002FBUILD.bazel\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ffa198;background-color:#490202\">\u003C\u002Fspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">+++ b\u002FBUILD.bazel\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">\u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff\">@@ -32,7 +32,10 @@ go_library(\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>     ],\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>     importpath = &#34;github.com\u002Fjinzhu\u002Fgorm&#34;,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>     visibility = [&#34;\u002F\u002Fvisibility:public&#34;],\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ffa198;background-color:#490202\">-    deps = [&#34;@com_github_jinzhu_inflection\u002F\u002F:inflection&#34;],\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ffa198;background-color:#490202\">\u003C\u002Fspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">+    deps = [\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">\u003C\u002Fspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">+        &#34;@com_github_jinzhu_inflection\u002F\u002F:inflection&#34;,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">\u003C\u002Fspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">+        &#34;@com_github_go_errors_errors\u002F\u002F:go_default_library&#34;,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">\u003C\u002Fspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">+    ],\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">\u003C\u002Fspan> )\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan> \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan> alias(\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#79c0ff\">@@ -76,5 +79,6 @@ go_test(\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>         &#34;\u002F\u002Fdialects\u002Fsqlite&#34;,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>         &#34;@com_github_erikstmartin_go_testdb\u002F\u002F:go-testdb&#34;,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>         &#34;@com_github_jinzhu_now\u002F\u002F:now&#34;,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">+        &#34;@com_github_go_errors_errors\u002F\u002F:go_default_library&#34;,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#56d364;background-color:#0f5323\">\u003C\u002Fspan>     ],\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan> )\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>加入到我们的patch中，然后再次编译，就正常了。\u003C\u002Fp>\n\n\u003Cp>我推断bazel patch这里面的逻辑是，先拉下原始包，第二步生成BUILD.bazel，最后再patch。google的研发bazel的人简直就是没长脑子，这样的步骤我还要它生成BUILD.bazel干啥，还不如直接把BUILD.bazel生成到patch文件里。总之，折腾了许久总算解决了，记录一下。\u003C\u002Fp>\n",{"id":31,"title":32,"uri":33,"author":10,"tags":34,"created_at":36,"view_count":37,"content":38},109,"初识串口","first-time-debug-serial-port",[35],"串口","2023-11-28 08:49:22",152,"\u003Cp>一直很想了解设备驱动编程。所以就从最基础，最简单的设备开始了解。串口，应该是所有设备中最简单最常见的设备。在linux中，有一种最简单的串口设备在\u003Ccode class=\"inline-code\">\u002Fdev\u003C\u002Fcode>下表现的是字符设备（c），字符设备可以被打开并且读写。\u003C\u002Fp>\n\n\u003Cp>我认识的第一个最简单的串口设备是一个usb接口的gps模块，如下图\n\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F11\u002Ffmvi8se8.webp\" alt=\"fmvi8se8\" \u002F>\n它是我目前为止，用过的最简单的串口设备，它只需要读，无需写，单向通讯，我只需要打开字符设备，然后不停的从中读取数据就可以了，里面的数据是GPS定位信息相关的字符串，根据它的文档，进行字段解析，就能获取到经纬度、时间、角度、速度等信息。我曾经用golang写过一个一个程序获取这些信息\n\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F11\u002Fsbtao9zf.png\" alt=\"sbtao9zf\" \u002F>\n这个程序，实际上可以算是一个用户态的设备驱动程序。\u003C\u002Fp>\n\n\u003Cp>我认识的第二个串口设备是一套蓝牙模块，用了usb转串口线连接蓝牙模块\n\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F11\u002Fddlsq0na.webp\" alt=\"ddlsq0na\" \u002F>\n按照设备的文档，我将它通过usb转串口线连接，然后将usb插上电脑，成功识别到串口。然后手机通过客服提供的调试app连接蓝牙信号，电脑上用串口读写软件将串口打开，手机上发送信息，电脑串口上能收到信息，电脑串口上还能发送特定的AT指令对设备进行查询与设置。\n\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F11\u002F3wwg8uas.webp\" alt=\"3wwg8uas\" \u002F>\n值得注意的是，我在连接模块的过程中，将usb转串口上的tx连接了模块tx，rx连接了模块的rx，导致无法收发消息，客服帮我找出问题并告诉我应该将tx连接rx，rx连接tx。想到这一点我恍然大悟，这跟rust里的\u003Ccode class=\"inline-code\">channel\u003C\u002Fcode>，go里的\u003Ccode class=\"inline-code\">chan\u003C\u002Fcode>，以及linux上的通用管道一样，都属于管道模型，对端的输出接入到设备的输入，对端才能将信息传给设备。后续我想我会进一步对这个蓝牙模块编写用户态驱动程序，进而尝试编写内核态驱动程序。\u003C\u002Fp>\n\n\u003Cp>其实早在我认识GPS串口设备之前，我也试过温湿度传感器DHT22，但是，这玩意儿根本不是串口，它只有一个数据接口(DATA)，也就是不像串口那样分rx,tx，它需要通过gpio口连接DATA针，然后通过高电位低电位来实现双向通讯，从而获取到温湿度数据。它既然不是串口设备那么也不能作为通用设备直插一般的电脑了。\u003C\u002Fp>\n\n\u003Cp>在我看来，程序能驱动物理设备，也是一件很有趣的事情。\u003C\u002Fp>\n",{"id":40,"title":41,"uri":42,"author":10,"tags":43,"created_at":47,"view_count":48,"content":49},108,"初学rust，如何实现在运行时对全局变量设置和读取","rust-how-to-set-and-get-global-variable-in-runtime",[44,45,46],"运行时","全局变量","读写","2023-11-01 22:11:16",599,"\u003Cp>在rust中，如何实现在运行时对全局变量设置和读取，这个问题困扰了我一段时间。因为在rust中，全局变量是不能在运行时修改的。rust的全局变量是属于全局静态变量，使用关键词\u003Ccode class=\"inline-code\">static\u003C\u002Fcode>来定义，如下：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">static\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>count: \u003Cspan style=\"color:#ff7b72\">usize\u003C\u002Fspan> \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">init_config\u003C\u002Fspan>(file_path: \u003Cspan style=\"color:#79c0ff\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">str\u003C\u002Fspan>)\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>count\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>count\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">+\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">1\u003C\u002Fspan>;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>编译器会告诉你修改\u003Ccode class=\"inline-code\">count\u003C\u002Fcode>不安全(unsafe)。\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>➜  las git:(feature\u002Fself-update-with-watcher-fork) ✗ cargo build\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   Compiling las v0.1.1 (\u002Froot\u002Fcode\u002Flas)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>error[E0133]: use of mutable static is unsafe and requires unsafe function or block\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>  --&gt; src\u002Fconfig\u002Fcfg.rs:35:13\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   |\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>35 |     count = count + 1;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   |             ^^^^^ use of mutable static\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   |\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>error[E0133]: use of mutable static is unsafe and requires unsafe function or block\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>  --&gt; src\u002Fconfig\u002Fcfg.rs:35:5\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   |\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>35 |     count = count + 1;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   |     ^^^^^^^^^^^^^^^^^ use of mutable static\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   |\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>For more information about this error, try `rustc --explain E0133`.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>error: could not compile `las` (bin &#34;las&#34;) due to 2 previous errors\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>一定要修改的话，需要加\u003Ccode class=\"inline-code\">unsafe\u003C\u002Fcode>块包裹住：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">static\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>count: \u003Cspan style=\"color:#ff7b72\">usize\u003C\u002Fspan> \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">init_config\u003C\u002Fspan>(file_path: \u003Cspan style=\"color:#79c0ff\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">str\u003C\u002Fspan>)\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">unsafe\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>count\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>count\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">+\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">1\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>};\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>但是，在rust中使用\u003Ccode class=\"inline-code\">unsafe\u003C\u002Fcode>是一件不好的事情，我们应该尽量避免使用\u003Ccode class=\"inline-code\">unsafe\u003C\u002Fcode>，这里有另一个方案可以实现在运行时设置全局变量，就是使用\u003Ccode class=\"inline-code\">once_cell\u003C\u002Fcode>这个包，虽然它的底层也是基于\u003Ccode class=\"inline-code\">unsafe\u003C\u002Fcode>来实现的，但是它对“不安全”代码进行了一定的包装。具体用法如下：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">static\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">CFG\u003C\u002Fspan>: \u003Cspan style=\"color:#f0883e;font-weight:bold\">OnceCell\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&lt;\u003C\u002Fspan>Conf\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&gt;\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>OnceCell::new();\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F 初始化和设置\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">init_config\u003C\u002Fspan>(file_path: \u003Cspan style=\"color:#79c0ff\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">str\u003C\u002Fspan>)\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">CFG\u003C\u002Fspan>.get_or_init(\u003Cspan style=\"color:#ff7b72;font-weight:bold\">|\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">|\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>load_config(file_path));\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F 读取\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">get_config\u003C\u002Fspan>()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>-&gt; \u003Cspan style=\"color:#79c0ff\">&amp;\u003C\u002Fspan>&#39;static \u003Cspan style=\"color:#f0883e;font-weight:bold\">Conf\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">CFG\u003C\u002Fspan>.get().unwrap()\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>可以看到，我们可以在运行时使用\u003Ccode class=\"inline-code\">once_cell\u003C\u002Fcode>的\u003Ccode class=\"inline-code\">get_or_init\u003C\u002Fcode>方法对全局变量进行初始化设置，它还有\u003Ccode class=\"inline-code\">set\u003C\u002Fcode>方法也可以在运行时对全局变量进行设置，\u003Ccode class=\"inline-code\">get\u003C\u002Fcode>方法在运行时对全局变量进行读取。从而实现不直接使用\u003Ccode class=\"inline-code\">unsafe\u003C\u002Fcode>块，来操作全局变量。而且\u003Ccode class=\"inline-code\">once_cell\u003C\u002Fcode>使用的全局变量完全不必申明为可变(\u003Ccode class=\"inline-code\">mut\u003C\u002Fcode>)变量。\u003C\u002Fp>\n\n\u003Cp>我们可以通过追踪\u003Ccode class=\"inline-code\">once_cell::get_or_init\u003C\u002Fcode>方法，可以看到在\u003Ccode class=\"inline-code\">initialize\u003C\u002Fcode>方法中\u003Ccode class=\"inline-code\">unsafe\u003C\u002Fcode>块中，将\u003Ccode class=\"inline-code\">value\u003C\u002Fcode>设置给了\u003Ccode class=\"inline-code\">*slot\u003C\u002Fcode>。\u003C\u002Fp>\n\n\u003Cp>\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F11\u002Fqby9tqm9.webp\" alt=\"qby9tqm9\" \u002F>\u003C\u002Fp>\n\n\u003Cp>可以看到，\u003Ccode class=\"inline-code\">once_cell\u003C\u002Fcode>对全局变量的操作进行了安全封装，因此，建议使用\u003Ccode class=\"inline-code\">once_cell\u003C\u002Fcode>进行全局变量的操作，而不是到处使用\u003Ccode class=\"inline-code\">unsafe\u003C\u002Fcode>块进行不安全的操作。\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>^注意\u003C\u002Fstrong>：实践证明，\u003Ccode class=\"inline-code\">OnceCell\u003C\u002Fcode>只能调用\u003Ccode class=\"inline-code\">set()\u003C\u002Fcode>对全局变量设置一次，后续再调用\u003Ccode class=\"inline-code\">set()\u003C\u002Fcode>就会报错。要反复读写甚至多线程中读写全局变量，应该使用\u003Ccode class=\"inline-code\">RwLock\u003C\u002Fcode>，详情参考新的文章\u003Ca href=\"https:\u002F\u002Fwww.duguying.net\u002Farticle\u002Fread-and-write-global-var-in-multi-thread-for-rust\">《初学rust，多线程中读写全局变量》\u003C\u002Fa>\u003C\u002Fp>\n",{"id":51,"title":52,"uri":53,"author":10,"tags":54,"created_at":57,"view_count":58,"content":59},106,"服务程序实现自己更新自己","how-a-service-upgrade-itself",[55,56],"服务","自更新","2023-10-13 17:42:30",377,"\u003Cp>作为一个广泛存在于众多设备上的常驻程序如何更新？他可以是一个agent，也可以是一个service，可以运行在众多容器中作为基础支持的程序，也可以运行在路由器、空调、洗衣机等家用设备或者物联设备上的支持程序。或许有些程序可以通过第三方平台进行更新，比如某些服务程序，配有专门的发版平台。但是更多的是无法通过发版平台发布的程序，比如是linux上的一个自启动的service，这个linux是你家里的路由器。这时候就需要程序自己更新自己了。\u003C\u002Fp>\n\n\u003Cp>程序更新通常有下列步骤，下载新的程序，替换旧的可执行文件和配置文件，重启程序（退出旧进程，拉起新进程）。\u003C\u002Fp>\n\n\u003Cp>程序自己如何去做这些操作？通常下载和替换文件并不难，只需要有一个接口能查询到新的程序版本和下载地址，很容易实现下载新版程序和替换。唯一需要注意一点的是重启程序这一步骤，这一步骤在业务程序进程上是无法实现的，因为它要拉起一个业务进程(worker)，并且退出自己，在它拉起业务进程的时候，如果自己本身就是业务进程(worker)，这样就会有两个业务进程(worker)，这对于大多数服务是不允许的，会出错。那么我们可以专门设计一个守护进程(watcher)仅用于程序的更新与重启。\u003C\u002Fp>\n\n\u003Cp>因此watcher进程里，更新程序和重启程序有如下流程\n\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F10\u002Fhhy70tzc.webp\" alt=\"hhy70tzc\" \u002F>\u003C\u002Fp>\n\n\u003Cp>下载替换与杀旧进程(worker)放在一个线程中，另一个线程只负责监视worker进程是否存在，如果worker进程不存在，则拉起worker进程。\u003C\u002Fp>\n\n\u003Cp>同一个程序中，如何区分worker进程与watcher进程？我这里使用的是特定环境变量来区分的。终端中拉起程序，默认启动的是watcher进程，watcher进程启动后检测到worker进程不存在，那么它将会通过\u003Ccode class=\"inline-code\">exec.Command\u003C\u002Fcode>拉起进程，并且注入特定环境变量，如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>cmd \u003Cspan style=\"color:#ff7b72;font-weight:bold\">:=\u003C\u002Fspan> exec.\u003Cspan style=\"color:#d2a8ff;font-weight:bold\">Command\u003C\u002Fspan>(procName, os.Args[\u003Cspan style=\"color:#a5d6ff\">1\u003C\u002Fspan>:]\u003Cspan style=\"color:#ff7b72;font-weight:bold\">...\u003C\u002Fspan>)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>cmd.Env = append(os.\u003Cspan style=\"color:#d2a8ff;font-weight:bold\">Environ\u003C\u002Fspan>(), \u003Cspan style=\"color:#a5d6ff\">&#34;PROC_FLAG=worker&#34;\u003C\u002Fspan>)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>cmd.Stdout = os.Stdout\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>cmd.Stderr = os.Stderr\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">if\u003C\u002Fspan> e \u003Cspan style=\"color:#ff7b72;font-weight:bold\">:=\u003C\u002Fspan> cmd.\u003Cspan style=\"color:#d2a8ff;font-weight:bold\">Start\u003C\u002Fspan>(); \u003Cspan style=\"color:#79c0ff\">nil\u003C\u002Fspan> \u003Cspan style=\"color:#ff7b72;font-weight:bold\">!=\u003C\u002Fspan> e {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\tlog.\u003Cspan style=\"color:#d2a8ff;font-weight:bold\">Printf\u003C\u002Fspan>(\u003Cspan style=\"color:#a5d6ff\">&#34;ERROR: %v\\n&#34;\u003C\u002Fspan>, e)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\t\u003Cspan style=\"color:#ff7b72\">return\u003C\u002Fspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>}\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>而且程序启动的时候，首先也会判断该环境变量是否存在，如果存在该环境变量，那么就进入业务进程的业务逻辑。如果不存在该环境变量，则进入守护进程的守护逻辑。\u003C\u002Fp>\n\n\u003Cp>这样一来就能够实现程序自己更新自己了。\u003C\u002Fp>\n",{"id":61,"title":62,"uri":63,"author":10,"tags":64,"created_at":68,"view_count":69,"content":70},105,"初学rust，没有途径修改argv[0]","can-not-modify-argv0-in-rust",[65,66,67],"argv0","rust","进程标题","2023-07-30 15:51:54",255,"\u003Cp>我们知道在C语言程序中，可以通过修改\u003Ccode class=\"inline-code\">argv[0]\u003C\u002Fcode>的值，来实现改变一个进程在\u003Ccode class=\"inline-code\">ps\u003C\u002Fcode>命令中显示的标题，先给一个C语言的demo如下：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">#\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">include\u003C\u002Fspan> \u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">&lt;stdio.h&gt;\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">#\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">include\u003C\u002Fspan> \u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">&lt;string.h&gt;\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">\u003C\u002Fspan>  \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">extern\u003C\u002Fspan> \u003Cspan style=\"color:#ff7b72\">char\u003C\u002Fspan> \u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>environ;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>  \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">int\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">main\u003C\u002Fspan>(\u003Cspan style=\"color:#ff7b72\">int\u003C\u002Fspan> argc , \u003Cspan style=\"color:#ff7b72\">char\u003C\u002Fspan> \u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>argv[]) {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    \u003Cspan style=\"color:#ff7b72\">int\u003C\u002Fspan> i;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>  \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">printf\u003C\u002Fspan>(\u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">argc:%d\u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff\">\\n\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan> , argc);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    \u003Cspan style=\"color:#ff7b72\">for\u003C\u002Fspan> (i \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan> \u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>; i \u003Cspan style=\"color:#ff7b72;font-weight:bold\">&lt;\u003C\u002Fspan> argc; i\u003Cspan style=\"color:#ff7b72;font-weight:bold\">+\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">+\u003C\u002Fspan>) {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>        \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">printf\u003C\u002Fspan>(\u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">argv[%d]:%s\u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff\">\\t\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0x%x\u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff\">\\n\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan> , i , argv[i], argv[i]);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>  \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    \u003Cspan style=\"color:#ff7b72\">for\u003C\u002Fspan> (i \u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan> \u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>; i \u003Cspan style=\"color:#ff7b72;font-weight:bold\">&lt;\u003C\u002Fspan> argc \u003Cspan style=\"color:#ff7b72;font-weight:bold\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&amp;\u003C\u002Fspan> environ[i]; i\u003Cspan style=\"color:#ff7b72;font-weight:bold\">+\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">+\u003C\u002Fspan>) {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>        \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">printf\u003C\u002Fspan>(\u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">evriron[%d]:%s\u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff\">\\t\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0x%x\u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff\">\\n\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan> , i , environ[i], environ[i]);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">strcpy\u003C\u002Fspan>(argv[\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>], \u003Cspan style=\"color:#79c0ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">nginx: process is shuting down\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">sleep\u003C\u002Fspan>(\u003Cspan style=\"color:#a5d6ff\">1000\u003C\u002Fspan>);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    \u003Cspan style=\"color:#ff7b72\">return\u003C\u002Fspan> \u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>}\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>进程原本的名称是\u003Ccode class=\"inline-code\">demo\u003C\u002Fcode>，但是我们通过\u003Ccode class=\"inline-code\">strcpy\u003C\u002Fcode>修改了\u003Ccode class=\"inline-code\">argv[0]\u003C\u002Fcode>之后，\u003Ccode class=\"inline-code\">ps\u003C\u002Fcode>命令显示进程的名称变为我们指定的\u003Ccode class=\"inline-code\">nginx: process is shuting down\u003C\u002Fcode>，如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>➜  build git:(master) ✗ ps -ef | grep nginx\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>root     1263942 1252322  0 15:29 pts\u002F2    00:00:00 nginx: process is shuting down\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>root     1263973 1253542  0 15:29 pts\u002F3    00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox nginx\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>这也是nginx程序实现在修改进程标题为\u003Ccode class=\"inline-code\">nginx: master\u003C\u002Fcode>, \u003Ccode class=\"inline-code\">nginx: worker\u003C\u002Fcode> 以及 \u003Ccode class=\"inline-code\">nginx: process is shuting down\u003C\u002Fcode> 的原理，从而实现在ps的标题中标识不同类别的进程。\u003C\u002Fp>\n\n\u003Cp>我们在rust语言中如何达到相同的效果呢，查阅资料了解到，通过下面方法可以修改进程名\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>nix::libc::{\u003Cspan style=\"color:#79c0ff;font-weight:bold\">PR_SET_NAME\u003C\u002Fspan>,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>prctl};\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>std::ffi::CString;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">main\u003C\u002Fspan>()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>new_name\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>CString::new(\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">NewProcessName\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>).expect(\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">CString::new failed\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">unsafe\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>prctl(\u003Cspan style=\"color:#79c0ff;font-weight:bold\">PR_SET_NAME\u003C\u002Fspan>,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>new_name.as_ptr()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">as\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">usize\u003C\u002Fspan>,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>但是实际使用后，发现，这种方法修改的进程名并不是\u003Ccode class=\"inline-code\">ps\u003C\u002Fcode>命令显示的进程标题，\u003Ccode class=\"inline-code\">ps\u003C\u002Fcode>命令显示的进程标题还是不变，而是修改了\u003Ccode class=\"inline-code\">pstree\u003C\u002Fcode>命令显示的进程树种的进程名称，所以，这种方法并不能达到我们想要的效果。\u003C\u002Fp>\n\n\u003Cp>我们尝试修改\u003Ccode class=\"inline-code\">argv[0]\u003C\u002Fcode>，在rust中是通过\u003Ccode class=\"inline-code\">env::args()\u003C\u002Fcode>来获取程序的传参，也即argv，追踪到\u003Ccode class=\"inline-code\">env::args()\u003C\u002Fcode>调用的是\u003Ccode class=\"inline-code\">env::args_os()\u003C\u002Fcode>，于是我们有这么一段代码尝试修改argv[0]：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>std::env;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>std::ffi::{CStr,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>CString,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>OsString};\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>std::os::unix::ffi::OsStringExt;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">set_process_title\u003C\u002Fspan>(title: \u003Cspan style=\"color:#79c0ff\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">str\u003C\u002Fspan>)\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>args: Vec\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&lt;\u003C\u002Fspan>OsString\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&gt;\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>env::args_os().collect();\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>argv: Vec\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&lt;\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">i8\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&gt;\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>args.iter()\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>.map(\u003Cspan style=\"color:#ff7b72;font-weight:bold\">|\u003C\u002Fspan>arg\u003Cspan style=\"color:#ff7b72;font-weight:bold\">|\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>arg_cstring\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>CString::new(arg.as_bytes()).expect(\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">Failed to create CString\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>arg_cstring.into_raw()\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>})\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>.collect();\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>argv.push(std::ptr::null_mut());\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>title_cstring\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>CString::new(title).expect(\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">Failed to create CString\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">unsafe\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>strcpy(argv[\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>]\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">as\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>c_char,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>title_cstring.as_ptr());\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">main\u003C\u002Fspan>()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>set_process_title(\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">MyWorker\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F 继续执行其他操作...\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>但是很遗憾，并没有修改argv[0]的效果，继续追踪\u003Ccode class=\"inline-code\">args_os()\u003C\u002Fcode>发现，其实在多个地方存在\u003Ccode class=\"inline-code\">clone()\u003C\u002Fcode>操作，我们获取到的\u003Ccode class=\"inline-code\">argv\u003C\u002Fcode>早就不是原始的\u003Ccode class=\"inline-code\">argv\u003C\u002Fcode>，\u003Ccode class=\"inline-code\">args_os()\u003C\u002Fcode>的实现如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">#[\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">stable(feature = \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">env\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">, since = \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">1.0.0\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">)\u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-weight:bold;font-style:italic\">]\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">args_os\u003C\u002Fspan>()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>-&gt; \u003Cspan style=\"color:#f0883e;font-weight:bold\">ArgsOs\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>ArgsOs\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>inner: \u003Cspan style=\"color:#f0883e;font-weight:bold\">sys\u003C\u002Fspan>::args::args()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>\u003Ccode class=\"inline-code\">sys::args::args()\u003C\u002Fcode>的实现如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#a5d6ff\">\u002F\u002F\u002F Returns the command line arguments\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#a5d6ff\">\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">args\u003C\u002Fspan>()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>-&gt; \u003Cspan style=\"color:#f0883e;font-weight:bold\">Args\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>imp::args()\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>\u003Ccode class=\"inline-code\">imp::args()\u003C\u002Fcode>的实现如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">args\u003C\u002Fspan>()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>-&gt; \u003Cspan style=\"color:#f0883e;font-weight:bold\">Args\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>Args\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>iter: \u003Cspan style=\"color:#f0883e;font-weight:bold\">clone\u003C\u002Fspan>().into_iter()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>这里\u003Ccode class=\"inline-code\">clone()\u003C\u002Fcode>实现如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">clone\u003C\u002Fspan>()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>-&gt; Vec\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&lt;\u003C\u002Fspan>OsString\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&gt;\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">unsafe\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F Load ARGC and ARGV, which hold the unmodified system-provided\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F argc\u002Fargv, so we can read the pointed-to memory without atomics\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F or synchronization.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F If either ARGC or ARGV is still zero or null, then either there\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F really are no arguments, or someone is asking for `args()`\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F before initialization has completed, and we return an empty\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F list.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>argv\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">ARGV\u003C\u002Fspan>.load(Ordering::Relaxed);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>argc\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">if\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>argv.is_null()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">else\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">ARGC\u003C\u002Fspan>.load(Ordering::Relaxed)\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>};\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>args\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>Vec::with_capacity(argc\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">as\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">usize\u003C\u002Fspan>);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">for\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>i\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">in\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">..\u003C\u002Fspan>argc\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>ptr\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>argv.offset(i)\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">as\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">const\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>libc::c_char;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F Some C commandline parsers (e.g. GLib and Qt) are replacing already\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F handled arguments in `argv` with `NULL` and move them to the end. That\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F means that `argc` might be bigger than the actual number of non-`NULL`\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F pointers in `argv` at this point.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F To handle this we simply stop iterating at the first `NULL` argument.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F `argv` is also guaranteed to be `NULL`-terminated so any non-`NULL` arguments\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u002F\u002F after the first `NULL` can safely be ignored.\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#8b949e;font-style:italic\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">if\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>ptr.is_null()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">                \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">break\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#79c0ff;font-weight:bold\">\u003C\u002Fspan>;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>cstr\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>CStr::from_ptr(ptr);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>args.push(OsStringExt::from_vec(cstr.to_bytes().to_vec()));\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>args\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>可以看到\u003Ccode class=\"inline-code\">argv\u003C\u002Fcode>是从\u003Ccode class=\"inline-code\">ARGV.load(Ordering::Relaxed);\u003C\u002Fcode>中加载出来的。可以看到argv经历了多次拷贝，最终才到args，然后通过\u003Ccode class=\"inline-code\">args_os()\u003C\u002Fcode>再呈现在我们面前，实际早就不再是最初的那个argv。\u003C\u002Fp>\n",{"id":72,"title":73,"uri":74,"author":10,"tags":75,"created_at":78,"view_count":79,"content":80},103,"端午游锦绣中华","splendid-china-garden-in-dragon-boat-festival",[76,77],"端午","锦绣中华","2023-06-25 09:40:39",101,"\u003Cp>\u003Cstrong>含苞待放的荷花\u003C\u002Fstrong>\u003C\u002Fp>\n\n\u003Cp>\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F06\u002F84ixt04a.webp\" alt=\"84ixt04a\" \u002F>\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>夜景灯展\u003C\u002Fstrong>\u003C\u002Fp>\n\n\u003Cp>\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F06\u002Fap8qyfq8.webp\" alt=\"ap8qyfq8\" \u002F>\u003C\u002Fp>\n\n\u003Cp>\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F06\u002Foagum0wj.webp\" alt=\"oagum0wj\" \u002F>\u003C\u002Fp>\n",{"id":82,"title":83,"uri":84,"author":10,"tags":85,"created_at":88,"view_count":89,"content":90},102,"2023年上半年简单回顾","review-the-half-year-of-2023",[86,87],"生活","回顾","2023-06-16 11:58:27",162,"\u003Cp>转眼间23年已经过了一半，简单回顾一下这半年的一些事情。\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>22年底12月份阳了，到了23年大家再也不关注新冠了\u003C\u002Fstrong>\u003C\u002Fp>\n\n\u003Cp>自从去年年底放开新冠防控之后，新冠在去年十二月份席卷全国，深圳万人空巷，就如同到了春节大家都回老家了一样，街头几乎见不到车辆与行人，阳了的人在家里躺着，没阳的人害怕阳了，不敢出门，但最终还是逃不过阳了。工作日公司办公室，整层楼到岗人数不足十人。\u003C\u002Fp>\n\n\u003Cp>阳了很难受，发烧两天才停止发烧，之后感觉自己气管就像被刮掉一层皮一样，气管里面咳出来的全是浓痰，咳嗽异物感严重。恢复之后，还连续干咳了一个多月，才逐渐消停。发烧的这两天，还去社康“求助”过，平日人很少的社康，塞满了人，社康门口全是病人排队付钱做抗原检测，因为全国全网都买不到抗原检测试剂盒，公司发的五份抗原检测试剂盒也很快被家人用完了，我发烧第一天在社康测抗原没测出来，医生开了点治疗感冒的中成药，问到退烧药，医生说早就已经没有了；第二天再去社康测抗原，强阳性，我就直接回家了，反正医生那边连退烧药都开不出来，去看医生也没用，好在家里还有一盒退烧药。那几天也有邻居到处借退烧药，分了2颗给别人。\u003C\u002Fp>\n\n\u003Cp>去年十二月份初次阳了之后，很长时间没有阳了，直到5月。大家都在传第二波新冠来了，然后5月底，我老婆二阳了，6月初，我也二阳了。第二轮感染新冠，只发烧了一晚上，吃了一颗退烧药，没多久就退烧了，第二天测出来强阳性，然后就是有点咽喉发炎，扁桃体的老毛病又犯了。乘着周末跑了一趟医院，医生开了点感冒药，然后咽喉含片，吃了两天，完全恢复了。总体来看，第二轮阳了病情比较轻，恢复也很快，遗留症状几乎没有。\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>困扰我多日的“牙齿”崩坏问题通过洗牙解决了\u003C\u002Fstrong>\u003C\u002Fp>\n\n\u003Cp>从去年开始，我的牙齿经常会因为咬到硬骨头就会崩下来一块，崩下来的东西外层黄色，内层黑色，还有臭味。我一度以为那是我牙齿的一部分骨质。再加上牙龈会出血，我以为我牙齿要坏掉了。于是挂了牙齿专科医院看了一下牙齿。医生看了之后，告诉我，我牙齿上全是结石，让我预约洗牙。最终，进洗牙室人生第一次洗了牙，那感觉真是“酸爽”，洗完之后，满嘴的血，牙龈出血严重。但是我照镜子之后才知道，原来我的牙齿可以这么白亮。遵医嘱，当天注意饮食，吃清淡的白粥，不受冷热刺激。到了第二天下午，出血的牙龈基本上已经完全恢复，留下的只有一口的白牙。为此我还嘚瑟了几天。洗掉了二三十年积累下来的牙结石之后，困扰我多日的牙龈出血问题终于解决了。\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>拖了四年多的驾校学习，终于拿到驾驶证了\u003C\u002Fstrong>\u003C\u002Fp>\n\n\u003Cp>另一件值得一提的事情就是，我在6月份终于拿到了驾驶证。困扰我多年的科一练题在二月份一个月的时间里终于解决了，其实找到科一练题的方法之后，科一并没有那么难。如果没有找到方法，去刷题库1000题或者精简题库500题，终究是反复折腾记了忘、忘了记。科二练习了5天，然后去考试，一把过。科三练习了3天，去考试，两把都是挂在终点。科三第二次考试，第一把也是挂在终点，因为终点掉灯之后忘记补灯了，第二把设备故障导致中断，重新补考第二把，终于完美通过了。科三考完回家第二天就阳了。最终，等了一个星期，完全恢复之后，练了差不多一个星期的科四题目，在周六去考了科四，终于拿到了驾驶证，成为了一个合法的驾驶员。\u003C\u002Fp>\n\n\u003Cp>时间过得真快，很多事情已经是物是人非了。估计下半年还会有更多值得回顾的事情。\u003C\u002Fp>\n",{"id":79,"title":92,"uri":93,"author":10,"tags":94,"created_at":98,"view_count":99,"content":100},"QQ账号在网页上一键登录的实现原理","why-qq-support-one-click-login-in-webpage",[95,96,97],"登录","鉴权","QQ","2023-05-19 20:24:44",671,"\u003Cp>我们经常可以在网页上看到QQ快捷登录，只需要点击一下QQ图像，不需要账号，不需要密码，不需要扫码，就可以直接登录了。\u003C\u002Fp>\n\n\u003Cp>\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F05\u002Fapnf6a4m.png\" alt=\"apnf6a4m\" \u002F>\u003C\u002Fp>\n\n\u003Cp>下面简单介绍一下这其中的原理，我们可以在浏览器请求中找到这么一个请求，如下图\u003C\u002Fp>\n\n\u003Cp>\u003Cimg src=\"https:\u002F\u002Fimage.duguying.net\u002F2023\u002F05\u002F4fnj1xbe.webp\" alt=\"4fnj1xbe\" \u002F>\u003C\u002Fp>\n\n\u003Cp>可以发现它请求的是\u003Ccode class=\"inline-code\">127.0.0.1:4301\u003C\u002Fcode>，很明显这个服务是一个本地服务，它就运行在你电脑上。其实它就是你QQ客户端上运行的一个服务，可以看到，请求了这个服务的接口之后，服务响应中设置了相关的cookies，后续，QQ系的网站就可以根据这个cookies进行鉴权了。\u003C\u002Fp>\n\n\u003Cp>所以说，要实现类似于QQ的这种一键登录能力，你需要有个本地客户端，客户端要提供一个http接口，你的网站会请求这个本地客户端，已鉴权的本地客户端收到这个网页上的请求之后，就会将当前登录账号的鉴权cookies植入到浏览器了，这样就成功的实现了一键快捷登录鉴权。这也就是所谓的桌面客户端为浏览器植入cookies的技术。\u003C\u002Fp>\n",{"id":102,"title":103,"uri":104,"author":10,"tags":105,"created_at":108,"view_count":109,"content":110},100,"初学rust，初始化一个C语言结构体","init-a-clang-struct-with-rust",[66,106,107],"clang","结构体","2023-05-15 20:09:33",151,"\u003Cp>最近用到了libc这个包，调用其中的\u003Ccode class=\"inline-code\">statfs\u003C\u002Fcode>函数，用于查询指定路径挂载的磁盘占用。可以看到\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">statfs\u003C\u002Fspan>(path: \u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">const\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>::c_char,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>buf: \u003Cspan style=\"color:#ff7b72;font-weight:bold\">*\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>statfs)\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>-&gt; ::c_int;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>\u003Ccode class=\"inline-code\">statfs\u003C\u002Fcode>第二个参数是一个C语言结构体\u003Ccode class=\"inline-code\">statfs\u003C\u002Fcode>，其定义如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">struct\u003C\u002Fspan> \u003Cspan style=\"color:#f0883e;font-weight:bold\">statfs\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_type: ::__fsword_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_bsize: ::__fsword_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_blocks: ::fsblkcnt_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_bfree: ::fsblkcnt_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_bavail: ::fsblkcnt_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_files: ::fsfilcnt_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_ffree: ::fsfilcnt_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_fsid: ::fsid_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_namelen: ::__fsword_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">pub\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>f_frsize: ::__fsword_t,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>f_spare: [::__fsword_t;\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">5\u003C\u002Fspan>],\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>如果用常规的rust初始化方法，必须填充结构体的各字段\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>x\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>statfs{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">..\u003C\u002Fspan>.,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>f_spare: \u003Cspan style=\"color:#ff7b72;font-weight:bold\">..\u003C\u002Fspan>.,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>可以看到其中\u003Ccode class=\"inline-code\">f_spare\u003C\u002Fcode>字段是一个数组，属于复杂类型，用rust的初始化方式，需要一个个字段的填充，而且需要填充为初始值0，将会非常复杂。其实有一种简单方法，使用\u003Ccode class=\"inline-code\">std::mem::zeroed\u003C\u002Fcode>函数即可。举例如下\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#ff7b72\">fn\u003C\u002Fspan> \u003Cspan style=\"color:#d2a8ff;font-weight:bold\">statfs\u003C\u002Fspan>(\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>self,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>mount_path: String)\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>-&gt; String {\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>x\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>CString::new(mount_path.as_bytes()).expect(\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">covert cstring failed\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>info\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>String::from(\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>statfs_buf\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">unsafe\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>std::mem::zeroed()\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>};\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">let\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>ret\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">unsafe\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>libc::statfs(x.as_ptr(),\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">mut\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>statfs_buf)\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>};\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">if\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>ret\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">0\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>{\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>info\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72;font-weight:bold\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>format!\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>(\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">{}\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">{}\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">{}\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\"> \u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">{}\u003C\u002Fspan>\u003Cspan style=\"color:#a5d6ff\">&#34;\u003C\u002Fspan>,\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">            \u003C\u002Fspan>statfs_buf.f_bsize,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>statfs_buf.f_blocks,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>statfs_buf.f_bfree,\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>statfs_buf.f_bavail\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">        \u003C\u002Fspan>);\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\">    \u003C\u002Fspan>\u003Cspan style=\"color:#ff7b72\">return\u003C\u002Fspan>\u003Cspan style=\"color:#6e7681\"> \u003C\u002Fspan>info;\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\u003Cspan style=\"color:#6e7681\">\u003C\u002Fspan>}\u003Cspan style=\"color:#6e7681\">\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>可以看到\u003Ccode class=\"inline-code\">std::mem::zeroed()\u003C\u002Fcode>方法，直接能够初始化一段0值的内存空间，这段空间具体大小，直接由下一行\u003Ccode class=\"inline-code\">libc::statfs(...)\u003C\u002Fcode>调用的第二个参数类型决定，由这一行直接能推导出该申请多大的0空间。\u003C\u002Fp>\n",{"title":112,"list":113},"最热文章",[114,120,126,132,138,144,150,156,162,168],{"id":115,"title":116,"uri":117,"author":10,"created_at":118,"view_count":119},28,"docker容器目录与主机目录同步","\u002Farticle\u002Fdocker容器目录与主机目录同步","2014-12-31 12:34:08",15570,{"id":121,"title":122,"uri":123,"author":10,"created_at":124,"view_count":125},21,"beego中使用fis","\u002Farticle\u002Fbeego中使用fis","2014-12-03 10:47:56",9250,{"id":127,"title":128,"uri":129,"author":10,"created_at":130,"view_count":131},20,"用github登录，oauth开发","\u002Farticle\u002F用github登录，oauth开发","2014-11-23 13:33:37",9113,{"id":133,"title":134,"uri":135,"author":10,"created_at":136,"view_count":137},18,"windows服务注册工具nssm","\u002Farticle\u002Fwindows服务注册工具nssm","2014-10-31 21:34:39",9047,{"id":139,"title":140,"uri":141,"author":10,"created_at":142,"view_count":143},49,"用latex排版中文书籍","\u002Farticle\u002F用latex排版中文书籍","2016-10-31 11:12:02",8634,{"id":145,"title":146,"uri":147,"author":10,"created_at":148,"view_count":149},19,"texlive中文书签乱码","\u002Farticle\u002Ftexlive中文书签乱码","2014-11-15 02:54:01",8461,{"id":151,"title":152,"uri":153,"author":10,"created_at":154,"view_count":155},6,"Windows上的软件包管理器chocolatey","\u002Farticle\u002FWindows上的软件包管理器chocolatey","2014-08-10 15:55:22",8009,{"id":157,"title":158,"uri":159,"author":10,"created_at":160,"view_count":161},3,"利用开源和免费资源搭建CI环境","\u002Farticle\u002F利用开源和免费资源搭建CI环境","2014-07-04 16:54:58",7732,{"id":163,"title":164,"uri":165,"author":10,"created_at":166,"view_count":167},16,"php-fpm网站目录权限配置","\u002Farticle\u002Fphp-fpm网站目录权限配置","2014-10-18 01:36:10",7274,{"id":169,"title":170,"uri":171,"author":10,"created_at":172,"view_count":173},27,"sublime text 2插件开发，外部修改文件无法重新加载","\u002Farticle\u002Fsublime text 2插件开发，外部修改文件无法重新加载","2014-12-26 20:24:13",7054,{"title":175,"list":176},"按月归档",[177,181,184,187,190,193,196,200,204,207,210,213,217,220,223,227,230,233,236,240,243,246,249,252,255,258,261,264,267,270,273,276,279,282,285,288,291,294,297,300,304,307,310,313,316,319],{"title":178,"uri":179,"view_count":180},"2026年7月","\u002Farchive\u002F2026\u002F7\u002F1","[1]",{"title":182,"uri":183,"view_count":180},"2026年1月","\u002Farchive\u002F2026\u002F1\u002F1",{"title":185,"uri":186,"view_count":180},"2025年4月","\u002Farchive\u002F2025\u002F4\u002F1",{"title":188,"uri":189,"view_count":180},"2024年6月","\u002Farchive\u002F2024\u002F6\u002F1",{"title":191,"uri":192,"view_count":180},"2024年5月","\u002Farchive\u002F2024\u002F5\u002F1",{"title":194,"uri":195,"view_count":180},"2024年4月","\u002Farchive\u002F2024\u002F4\u002F1",{"title":197,"uri":198,"view_count":199},"2023年12月","\u002Farchive\u002F2023\u002F12\u002F1","[6]",{"title":201,"uri":202,"view_count":203},"2023年11月","\u002Farchive\u002F2023\u002F11\u002F1","[2]",{"title":205,"uri":206,"view_count":180},"2023年10月","\u002Farchive\u002F2023\u002F10\u002F1",{"title":208,"uri":209,"view_count":180},"2023年7月","\u002Farchive\u002F2023\u002F7\u002F1",{"title":211,"uri":212,"view_count":203},"2023年6月","\u002Farchive\u002F2023\u002F6\u002F1",{"title":214,"uri":215,"view_count":216},"2023年5月","\u002Farchive\u002F2023\u002F5\u002F1","[3]",{"title":218,"uri":219,"view_count":203},"2023年4月","\u002Farchive\u002F2023\u002F4\u002F1",{"title":221,"uri":222,"view_count":203},"2023年3月","\u002Farchive\u002F2023\u002F3\u002F1",{"title":224,"uri":225,"view_count":226},"2023年2月","\u002Farchive\u002F2023\u002F2\u002F1","[5]",{"title":228,"uri":229,"view_count":180},"2023年1月","\u002Farchive\u002F2023\u002F1\u002F1",{"title":231,"uri":232,"view_count":203},"2022年12月","\u002Farchive\u002F2022\u002F12\u002F1",{"title":234,"uri":235,"view_count":226},"2022年11月","\u002Farchive\u002F2022\u002F11\u002F1",{"title":237,"uri":238,"view_count":239},"2022年10月","\u002Farchive\u002F2022\u002F10\u002F1","[4]",{"title":241,"uri":242,"view_count":199},"2022年9月","\u002Farchive\u002F2022\u002F9\u002F1",{"title":244,"uri":245,"view_count":226},"2022年8月","\u002Farchive\u002F2022\u002F8\u002F1",{"title":247,"uri":248,"view_count":180},"2019年7月","\u002Farchive\u002F2019\u002F7\u002F1",{"title":250,"uri":251,"view_count":180},"2019年2月","\u002Farchive\u002F2019\u002F2\u002F1",{"title":253,"uri":254,"view_count":180},"2018年9月","\u002Farchive\u002F2018\u002F9\u002F1",{"title":256,"uri":257,"view_count":180},"2018年8月","\u002Farchive\u002F2018\u002F8\u002F1",{"title":259,"uri":260,"view_count":180},"2017年11月","\u002Farchive\u002F2017\u002F11\u002F1",{"title":262,"uri":263,"view_count":180},"2017年8月","\u002Farchive\u002F2017\u002F8\u002F1",{"title":265,"uri":266,"view_count":180},"2017年5月","\u002Farchive\u002F2017\u002F5\u002F1",{"title":268,"uri":269,"view_count":180},"2017年4月","\u002Farchive\u002F2017\u002F4\u002F1",{"title":271,"uri":272,"view_count":180},"2016年11月","\u002Farchive\u002F2016\u002F11\u002F1",{"title":274,"uri":275,"view_count":180},"2016年10月","\u002Farchive\u002F2016\u002F10\u002F1",{"title":277,"uri":278,"view_count":203},"2016年9月","\u002Farchive\u002F2016\u002F9\u002F1",{"title":280,"uri":281,"view_count":180},"2016年8月","\u002Farchive\u002F2016\u002F8\u002F1",{"title":283,"uri":284,"view_count":203},"2016年7月","\u002Farchive\u002F2016\u002F7\u002F1",{"title":286,"uri":287,"view_count":226},"2016年6月","\u002Farchive\u002F2016\u002F6\u002F1",{"title":289,"uri":290,"view_count":180},"2015年12月","\u002Farchive\u002F2015\u002F12\u002F1",{"title":292,"uri":293,"view_count":180},"2015年10月","\u002Farchive\u002F2015\u002F10\u002F1",{"title":295,"uri":296,"view_count":203},"2015年2月","\u002Farchive\u002F2015\u002F2\u002F1",{"title":298,"uri":299,"view_count":180},"2015年1月","\u002Farchive\u002F2015\u002F1\u002F1",{"title":301,"uri":302,"view_count":303},"2014年12月","\u002Farchive\u002F2014\u002F12\u002F1","[8]",{"title":305,"uri":306,"view_count":203},"2014年11月","\u002Farchive\u002F2014\u002F11\u002F1",{"title":308,"uri":309,"view_count":226},"2014年10月","\u002Farchive\u002F2014\u002F10\u002F1",{"title":311,"uri":312,"view_count":216},"2014年9月","\u002Farchive\u002F2014\u002F9\u002F1",{"title":314,"uri":315,"view_count":216},"2014年8月","\u002Farchive\u002F2014\u002F8\u002F1",{"title":317,"uri":318,"view_count":216},"2014年7月","\u002Farchive\u002F2014\u002F7\u002F1",{"title":320,"uri":321,"view_count":203},"2013年9月","\u002Farchive\u002F2013\u002F9\u002F1",104,{"url":324,"title":325},"https:\u002F\u002Fimage.duguying.net\u002F2022\u002F09\u002Fij6x8o4s.webp","老家 摄于2020年秋",1790062265345]