<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>配置管理 on Time Friend</title><link>https://time-friend.com/zh/tags/%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86/</link><description>Recent content in 配置管理 on Time Friend</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Sat, 05 Sep 2026 10:00:00 +0000</lastBuildDate><atom:link href="https://time-friend.com/zh/tags/%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86/index.xml" rel="self" type="application/rss+xml"/><item><title>Eden 模拟器配置每次崩溃就被重置: 从 C++ 源码的非原子写入讲起</title><link>https://time-friend.com/zh/archive/eden-config-reset-non-atomic-write/</link><pubDate>Sat, 05 Sep 2026 10:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/eden-config-reset-non-atomic-write/</guid><description>&lt;p&gt;Eden 里的设置总是莫名其妙回到默认, 尤其在我把模拟器强杀、或者它自己崩溃之后。图形驱动、内存布局、语言区域, 全部复位。我一开始以为是 Android 什么时候把应用数据清了, 先后重装过两次, 还在手机上给它开了各种后台保活。重装能好一阵, 然后又犯。&lt;/p&gt;
&lt;p&gt;真正的原因和 Android 没关系, 在 Eden 自己的源码里。&lt;/p&gt;
&lt;h2 id="不是没保存-是保存到一半被截断"&gt;不是&amp;quot;没保存&amp;quot;, 是&amp;quot;保存到一半被截断&amp;quot;&lt;/h2&gt;
&lt;p&gt;配置存在 &lt;code&gt;files/config/config.ini&lt;/code&gt;。Eden 保存设置的写法, 是把整个文件重新写一遍。问题在打开文件的模式上:&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Config&lt;span style="color:#f92672"&gt;::&lt;/span&gt;WriteToIni() &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fopen(config_loc.c_str(), &lt;span style="color:#e6db74"&gt;&amp;#34;wb&amp;#34;&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// &amp;#34;wb&amp;#34; 一打开就把文件截断为 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; config&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;Save(writer, false); &lt;span style="color:#75715e"&gt;// 再逐项写入；若此刻崩溃 → 文件残缺
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Config&lt;span style="color:#f92672"&gt;::&lt;/span&gt;Reload() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ReadValues(); &lt;span style="color:#75715e"&gt;// 读现有配置
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; SaveValues(); &lt;span style="color:#75715e"&gt;// 立刻又写回去
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;&amp;quot;wb&amp;quot;&lt;/code&gt; 这个模式在 POSIX 里的语义是: 打开即把文件截断成 0 字节, 然后从零开始写。也就是说, 从打开到写完的这段时间里, 磁盘上的 &lt;code&gt;config.ini&lt;/code&gt; 处于&amp;quot;已经被清空、还没写回来&amp;quot;的状态。如果在这段窗口里进程被强杀或崩溃, 留下的就是一个残缺或空白的文件。下一次启动去解析它, 解析失败, Eden 就回退到内置默认值——看到的现象就是&amp;quot;配置被重置&amp;quot;。&lt;/p&gt;
&lt;p&gt;这还没完。&lt;code&gt;Reload()&lt;/code&gt; 每次启动都会先读、再立刻写回去。也就是说每次启动都有一个这样的写入窗口, 崩溃并不需要多罕见。写配置本身不是原子的(没有先写临时文件再 &lt;code&gt;rename&lt;/code&gt;), 这是根因。&lt;/p&gt;</description></item></channel></rss>