<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Posts on linxy&#39;s blog</title>
    <link>https://linxy.dev/posts/</link>
    <description>Recent content in Posts on linxy&#39;s blog</description>
    <image>
      <title>linxy&#39;s blog</title>
      <url>https://linxy.dev/images/papermod-cover.png</url>
      <link>https://linxy.dev/images/papermod-cover.png</link>
    </image>
    <generator>Hugo -- 0.152.2</generator>
    <language>en</language>
    <copyright>linxy&amp;rsquo;s blog</copyright>
    <lastBuildDate>Fri, 12 Dec 2025 17:46:16 +0800</lastBuildDate>
    <atom:link href="https://linxy.dev/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>2025的Linux之旅</title>
      <link>https://linxy.dev/posts/2025-linux/</link>
      <pubDate>Fri, 12 Dec 2025 17:46:16 +0800</pubDate>
      <guid>https://linxy.dev/posts/2025-linux/</guid>
      <description>&lt;p&gt;在AI潮流盛行的今天，Windows也免不了俗气，在本来就很臃肿，缓慢的系统中，加入所谓的Copilot，但是又不让中国人用，可以说是白白在消耗电。加上Windows11的BUG越来越多，Explorer运行缓慢，越更新反而游戏帧数越低，等等大大小小的问题，数不胜数。就这些问题，让我不禁思考，使用一个纯粹的操作系统，是很有必要的。在最近研究了一些配置后，发现目前Linux已经完全可以满足日常使用了，我写这篇文章也是为了记录一下转型，希望对你有所帮助。&lt;/p&gt;
&lt;h1 id=&#34;发行版&#34;&gt;发行版&lt;/h1&gt;
&lt;p&gt;先从发行版开始，我选择的发行版是&lt;a href=&#34;https://cachyos.org&#34;&gt;CachyOS&lt;/a&gt;。在使用了很多发行版后，最终在CachyOS中停下了脚步，目前已经两年多没有换过系统了，比我的Win11的寿命长，原因很简单，开发团队技术力与开放程度，还有审美都是在线。在这之前，我使用的是ArcoLinux，这个发行版配置项其实也行，但是审美太差了，做的太过于受工程师文化影响了，处处都显得粗糙；搜了一下这个发行版已经停更了，在CachyOS面前我觉得这种小作坊已经没有空间了。&lt;/p&gt;
&lt;p&gt;CachyOS优点很多：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装简单，开箱可用，各个桌面都已经配置好了，但是又不是非常的个性化，属于是普罗大众都能接受的程度。比如Hyperland配置的美观又保守，不会说安装完之后还要人去翻文档看切Desktop是什么快捷键。&lt;/li&gt;
&lt;li&gt;游戏方面打包了一个单独的meta库，在官网的wiki上也包括了很多关于怎么在Linux玩游戏的配置，也打包了各种各样的包，方便一键安装，可以直接游玩。&lt;/li&gt;
&lt;li&gt;可调优的配置多，光是内核版本就很多，还可以用GUI去配置各种内核选项与配置，调度器等。包也有自己开启了lto等优化选项的包，这种对于普通PC用户来说，性能的增加可能是可有可无，但是至少能带来一些心理安慰。&lt;/li&gt;
&lt;li&gt;保持了Arch Linux原来的样子，很多基于Arch的发行版都会做自己的一些特色的修改，但是Cachy只做了调优，也就是说，不会用Manjora一样出现属于自己的BUG，反馈也无法反馈到上游；好处是出了问题，看Arch Linux的wiki就可以解决了。&lt;/li&gt;
&lt;li&gt;文档全面，CachyOS的wiki至少写的让人有想看想用的欲望。在当下，网站的美观程度真的会给人增加很多的印象分。&lt;br&gt;
&lt;img loading=&#34;lazy&#34; src=&#34;https://linxy.dev/images/cachy.png&#34;&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&#34;桌面&#34;&gt;桌面&lt;/h1&gt;
&lt;p&gt;我选的是CachyOS开箱即用的KDE，Plasma是一个开放与易用性都不错的桌面，用起来让人不会有那种“这个系统好粗糙的感觉”，安装之后不需要折腾，即得到了一个相对完善的桌面，可以说是最适合Windows用户切换过来的了。相比之下，gnome就显的很粗糙，安装之后还要装插件，装的插件未必能用，gnome shell更新很激进，经常会遇到主题，插件等，上个版本能用，下个版本就改掉了的情况。&lt;/p&gt;
&lt;p&gt;由于CachyOS配置的KDE已经很不错了，我只做了一些简单的调优，针对自己的习惯改了一些快捷键。KDE的强大之处也有可配置的地方多。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dolphin可以在配置中修改展示模式，是list还是icon，以及显示哪些属性，还有工具栏的样式与按钮。我就给增加了一个回到上级目录的按钮，符合使用Windows的习惯。&lt;/li&gt;
&lt;li&gt;修改了krunner的显示位置，这个在设置中可以找到，显示在屏幕中间，可以比较像Spotlight，聊胜于无吧。&lt;/li&gt;
&lt;li&gt;安装了&lt;code&gt;kdeplasma-addons&lt;/code&gt;，这个包增加了一些小功能，比如农历。安装完之后，在Digit Clock的配置中即可找到Alternate calendar。另外还给Krunner增加了单位转换等功能。&lt;/li&gt;
&lt;li&gt;主题使用&lt;a href=&#34;https://github.com/vinceliuice/WhiteSur-kde&#34;&gt;White-sur&lt;/a&gt;。需要安装 &lt;a href=&#34;https://github.com/tsujan/Kvantum/blob/master/Kvantum/INSTALL.md#distributions&#34;&gt;Kvantum&lt;/a&gt;，如果想达到跟mac一样的效果，需要安装latte-dock，但是我不喜欢dock。&lt;/li&gt;
&lt;li&gt;原有快捷键&lt;code&gt;Win+D&lt;/code&gt;显示桌面，&lt;code&gt;Win+W&lt;/code&gt;显示所有的窗口，&lt;code&gt;Win+G&lt;/code&gt;显示所有的窗口，包含了多桌面，显示，&lt;code&gt;Win+G&lt;/code&gt;模式下的的缩略窗口可以自由拖动。&lt;code&gt;Alt+~&lt;/code&gt;可以切换同一个软件的不同窗口。在显示了所有的窗口的情况下，可以在顶部新建虚拟桌面，可以在任务栏上用鼠标点击或者用滚轮切换桌面，也可以单纯把鼠标放在桌面上切换虚拟桌面。在设置中可以配置窗口自动往哪些桌面排布，不过目前我还没有这种需求。&lt;code&gt;Alt+Tab&lt;/code&gt;即是Windows中那种切换任务的方式，但是个人感觉没有&lt;code&gt;Win+G&lt;/code&gt;好用&lt;/li&gt;
&lt;li&gt;右下角有一个显示所有窗口的触发角，个人感觉不是很好用，因为右下角有一个显示所有窗口的区域，与Windows相似，在交互上，人往往把鼠标往角落拖到底，期待桌面把指针挡住，但是加了触发角之后会增加这个动作的心智负担，于是我给关掉了，改用快捷键。&lt;/li&gt;
&lt;li&gt;桌面壁纸与小组件见仁见智，添加自己喜欢的就行了，我只加了一个总覧的小组件，桌面的图标可以在桌面右键菜单中选择是横排还是竖排，大小等。可惜的是，KDE没有类似于Fence的软件。&lt;/li&gt;
&lt;li&gt;鼠标放在音量图标上可以直接调节音量，原来Windows10是有这个功能，现在好像去掉了。也是Windows的一个退步吧。&lt;/li&gt;
&lt;li&gt;有些人喜欢跟Mac一样的全局菜单栏，但是我感觉有点本末倒置，没必要追求这样的效果，而且可能会有兼容性问题，于是就不想折腾了，省心比较重要，如果你喜欢，可以直接使用小组件&lt;code&gt;Global Menu&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;双屏可以开箱即用，而且与X.org时代不一样的是，AMD+wayland目前易用性很强，wayland最大的一个改进是，目前终于可以双屏使用不同的缩放比例了，以前在X.org下，还得用xrandr各种调，效果感人。&lt;/li&gt;
&lt;li&gt;修改了一个全局快捷键&lt;code&gt; Ctrl+Alt+Shift+A&lt;/code&gt;用于唤起&lt;code&gt;Spectacle&lt;/code&gt; 自选区域截图然后Copy到粘贴板中。纯属于习惯了QQ的截图快捷键，但是NT QQ在Linux的截图模块用不了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;软件&#34;&gt;软件&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;浏览器：Vivaldi，我在所有的平台上使用的都是使用Vivaldi，Vivaldi由前opera员工打造，营业模式好像是duckduckgo给他们打钱，然后维持了一个小而美的团队。在别的浏览器的功能越加越多，加上一些不知所谓的功能的时候，Vivaldi只加上一些实用的功能，而且都是投票出来的功能，比如各种个性化的tab样式，地址栏位置。像之前全网都在追的垂直标签页，Vivaldi早早就加上了；一些尝试性的功能，比如邮件日历等功能，Vivaldi给了开关，可以不使用，给了用户选择。另外我觉得，最大的问题是：Chrome把Mainfest V2的支持砍掉了，很多插件都用不了了，Edge居然在浏览器上加上了所谓的&lt;code&gt;Copilot&lt;/code&gt;，广告满天飞，越来越重，这些都使得Vivaldi的存在越来越珍贵，推荐大家都使用Vivaldi。&lt;/li&gt;
&lt;li&gt;聊天：因为信创的存在，目前QQ，微信都有了Linux版本，虽然NTQQ Linux版本BUG不少，经常性的使用一段时间后，粘贴板就坏了，需要重启，但是总比以前使用Wine版本的QQ要好。Telegram可以选择的就很多了，不多赘述。飞书也是有aur包的，但是我没试过。&lt;/li&gt;
&lt;li&gt;音乐：同样因为信创，QQ音乐也有了客户端了，虽然UI有时候会鬼畜。但是总比没有强，功能上比Windows版本少一点，好像雷达功能就没有。相反的，网易云音乐以前的客户端早就停更了，目前只有在官网的下载页中的Linux系统下载中藏了一个很深的Web版的网易云的链接还能用。&lt;/li&gt;
&lt;li&gt;离线视频：Linux上好像并没有一个PotPlayer这样的视频软件，VLC长的太丑，mpv太过简单，想要好用还得配置，比较好用的就是SMPlayer了，但是也只是mpv包了一层，反正选啥都一样。&lt;/li&gt;
&lt;li&gt;在线视频：追番可以使用&lt;a href=&#34;https://github.com/open-ani/animeko&#34;&gt;animeko&lt;/a&gt;，集找番、追番、看番的一站式弹幕追番平台，云收藏同步 (Bangumi)，离线缓存，BitTorrent，弹幕云过滤。Emby客户端可以用&lt;a href=&#34;https://github.com/tsukinaha/tsukimi&#34;&gt;tsukimi&lt;/a&gt;，迭代了之后也很好用了。&lt;/li&gt;
&lt;li&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://linxy.dev/images/emby.png&#34;&gt;&lt;/li&gt;
&lt;li&gt;文本编辑器：KDE自带的Kate就已经很好用了，对于轻量编辑文件，看txt够用了，对比Notepad来说功能多了很多，又不失轻量。但是要是要说Notepad++那种打开超大文本又不卡的编辑器，好像Linux还真没有。&lt;/li&gt;
&lt;li&gt;代码编辑器：不多说，vscode与cursor不可少。另外目前zed在Linux使用上还算可以，属于到了一个可以使用的程度了。&lt;/li&gt;
&lt;li&gt;终端：&lt;code&gt;alacritty&lt;/code&gt;,&lt;code&gt;ghostty&lt;/code&gt;,&lt;code&gt;konsole&lt;/code&gt;，&lt;code&gt;kitty&lt;/code&gt;随便选一个吧，都大差不差，CachyOS默认使用的是alacritty，带有一套主题，实用性还可以，但是alacritty团队对加新feature好像很抵触。ghostty是新贵，由zig写的，美观程度上比alacritty好不少。kitty应该是这些里面性能最好的。&lt;/li&gt;
&lt;li&gt;Neovim: 一个还算可以的，在配置整合与自由度还有社区的版本：&lt;a href=&#34;https://astronvim.com&#34;&gt;Astronvim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;IDE：唯一指定品牌Jetbrains，安装了tools box之后就可以安装自己想要的IDE了，其中RustRover与Clion Nova，IDEA都是个人免费的。&lt;/li&gt;
&lt;li&gt;LLM Client：&lt;a href=&#34;https://www.cherry-ai.com&#34;&gt;Cherry studio&lt;/a&gt;，cherry studio可以将通过webadv将配置保存在云盘中，实现同步。&lt;/li&gt;
&lt;li&gt;云盘：onedriver有一个非官方的实现:&lt;a href=&#34;https://github.com/abraunegg/onedrive&#34;&gt;onedriver&lt;/a&gt;。我用的坚果云在aur有打包，安装后，可以直接使用，虽然GUI可能会有缩放的问题，但是自动同步的功能是没问题的。&lt;/li&gt;
&lt;li&gt;NAS相关：在使用Windows中，我发现Exploer对smb的支持挺好的，dolphin用起来就比较费劲了，在搜索之后发现了有smb4k这个软件，因为我把自动发现关掉了，在加上了bookmark之后，就可以实现挂载好smb，直接访问了。注意bookmark的location要写全路径。&lt;/li&gt;
&lt;li&gt;笔记软件：我用的Obsidian，同步使用的坚果云。使用了一个小而美的配置，而不多折腾，也没用很多插件。笔记软件要写起来最重要。但是这套同步不能在手机上用，一些要同步的笔记我就往flomo上写了。&lt;/li&gt;
&lt;li&gt;TODO软件：滴答清单在aur上也有打包，而且使用体验感也很不错，与其它平台的并没有什么不一样。之前仔细研究过，好像滴答清单每一个平台的UI都是一样的，但是使用的技术却不是一样的，比如iOS与Windows，还有Web，感觉并不是使用的跨平台框架来实现的，而是多个平台使用了同一套UI，然后写了不同的代码。&lt;/li&gt;
&lt;li&gt;Office：可以用WPS，基本做到了开箱即用，但是复杂的文档还是会与Office套件有差距。&lt;/li&gt;
&lt;li&gt;录屏：用OBS吧。&lt;/li&gt;
&lt;li&gt;输入法：Fcitx-5，这个看&lt;a href=&#34;https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland&#34;&gt;文档&lt;/a&gt;就可以配置好的，主要是中文输入法+Wayland，并不是开箱就能用的。&lt;/li&gt;
&lt;li&gt;阅读：有Web版本的微信读书，可以全平台同步。如果要使用软件，可以使用&lt;a href=&#34;https://github.com/readest/readest&#34;&gt;Readest&lt;/a&gt;, 同样是全平台同步，而且自定义的选项多，配合lxgw字体，阅读体验很不错。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;终端软件&#34;&gt;终端软件&lt;/h1&gt;
&lt;p&gt;在Rust出现之后，终端的软件可以说是越来越多，越来越好用，当然不仅限于Rust，就是百花齐放。我觉得最大的受益者是Windows平台。以前Windows上的终端软件简直少的可怜，又难用，还要用msys2来跑。
一些我在CachyOS用的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aristocratos/btop&#34;&gt;btop&lt;/a&gt;，htop的美化版。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bootandy/dust&#34;&gt;dust&lt;/a&gt;，排查磁盘哪个文件夹占的比较大。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/zellij-org/zellij&#34;&gt;zellij&lt;/a&gt;, 一个rust写的&amp;quot;tmux&amp;quot;，在快捷键与UI上比tmux好用不少，但是性能比tmux差很多，主要原因是UI tree在设计的时候就做的不好，大量的字符更新的时候，做不到差异更新panel里的东西，所以重绘性能很低。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sharkdp/fd&#34;&gt;fd&lt;/a&gt;，一个rust写的find，又快又实用，Option中的-x可以对每个文件做操作，在传统命令行使用中，需要用find出来然后pipe给xargs去执行命令，但是fd可以直接对结果执行命令。其它还有很多实用的选项。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/BurntSushi/ripgrep&#34;&gt;rg&lt;/a&gt;, 伟大无需多言。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/starship/starship&#34;&gt;starship&lt;/a&gt;，一个shell的prompt生成器，对大部分的shell都有直接可用的配置，简单又美观，比起以前配置oh my zsh等快速实用了很多，唯一的问题就是git太卡了，在大的repo里面卡的不行，可以考虑把大的git目录排除掉。&lt;/li&gt;
&lt;li&gt;eza，Cachyos默认用的就这个，一个更美观的ls，lsd与exa的接替者。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ajeetdsouza/zoxide&#34;&gt;zoxide&lt;/a&gt;, 一个记住了历史访问目录的小工具，按下z之后，即可直接跳转符合关键字的目录，非常实用。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/atuinsh/atuin&#34;&gt;atuin&lt;/a&gt;, 一个跨平台的命令行历史记录工具，可以保存在云端，实现跨平台保存，会有一个分数用于排行，同时实现了fzf类似的查找效果。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;游戏&#34;&gt;游戏&lt;/h1&gt;
&lt;p&gt;因为Valve做了Steam deck，他们对proton的投入很大，使得现在基于dxvk的proton可以跑大多数的Windows游戏，但是如果有反作弊的游戏是玩不了的，这些内容在CachyOS中写的很清楚了：&lt;a href=&#34;https://wiki.cachyos.org/configuration/gaming/&#34;&gt;wiki&lt;/a&gt;
我试过的Steam游戏都是能玩的，网络游戏玩过暗黑四，但是加速器的问题就解决不了，只能说打单机肯定是够用了&lt;/p&gt;</description>
    </item>
    <item>
      <title>Rust Atomic 笔记</title>
      <link>https://linxy.dev/posts/rust-atomic/</link>
      <pubDate>Thu, 10 Apr 2025 17:25:14 +0800</pubDate>
      <guid>https://linxy.dev/posts/rust-atomic/</guid>
      <description>&lt;h1 id=&#34;basic-of-rust-concurrency&#34;&gt;basic of rust concurrency&lt;/h1&gt;
&lt;p&gt;内部可变性是指可以通一个不可变引用来实现对内部数据的修改。标准库中有&lt;code&gt;Cell&amp;lt;T&amp;gt;&lt;/code&gt;，Cell相当于持有这个Obj，要做修改只能先把T move出来再把T塞回去。&lt;code&gt;RefCell&amp;lt;T&amp;gt;&lt;/code&gt;不但持有这个obj，还会维护一个引用计数，如果在运行时有多个Mut借用时，会panic。&lt;br&gt;
&lt;code&gt;RwLock&lt;/code&gt;是多线程版本的&lt;code&gt;RefCell&lt;/code&gt;，但是多个可变借用时，或者说多个写时，会block住试图拿这个可变借用的线程，让它进入sleep。而&lt;code&gt;Mutex&lt;/code&gt;不像Rwlock可以实现多个可读借用，mutex是彻底的独占的，其它线程都必须等待锁的释放。&lt;br&gt;
&lt;code&gt;UnSafeCell&lt;/code&gt;是实现内部可变性的关键类型，它只有get函数可以得到一个底层类型的raw pointer,&lt;code&gt;UnsafeCell&lt;/code&gt;没有任何保证安全性的限制，需要用户自己来进行安全性的保证。一般不会直接用unsafe cell，都是包装成另一个类型来限制使用，比如实现成cell或者mutex。&lt;br&gt;
&lt;code&gt;Send&lt;/code&gt;trait意味着这个类型的所有权可以在线程之间转移，&lt;code&gt;Sync&lt;/code&gt;trait意味着这个类型可以在线程之间共享。&lt;br&gt;
一个struct如果所有的类型都是send和sync，那它本身也是send和sync的，如果要实现非send和sync的话，可以用phontomdata 标记类型。PhantomData用于标记Struct非sync，毕竟这是个zero sized type。&lt;br&gt;
给一些非auto trait实现send和sync是unsafe的，因为取决于其中类型的具体实现，所以安全性需要自己来保证。&lt;br&gt;
rust的mutex，实现了一个其它线程如果持有了mutex，但是panic了，这个mutex就是poison的机制：&lt;a href=&#34;https://doc.rust-lang.org/std/sync/struct.Mutex.html#poisoning&#34;&gt;rust mutex doc&lt;/a&gt;。
mutex一些值得注意的点:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;if let的scope。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Some&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unwrap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//会lock到这个if结束
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;process_item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unwrap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Some&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//在进入body前，MutxGuard就已经drop掉了。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;do_something&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;rust 2024做出的一个if let的小修改，即if let的表达式生命周期不会延长到else body中去：&lt;a href=&#34;https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html&#34;&gt;rust 2024 doc&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;大多数的读写锁的实现都会block新的读者出现，当写者等待时，因为可能会多个读者共享导致写者一直要等待，这是读写锁中一个经典的饥饿问题。
## parking and condition variables
当一个线程在等待别的线程的通知的时候，这种叫thread parking，parking的时候，线程会进入睡眠，唤醒可以用unpark。
在实现上，unpark有一个很重要的特性是，有一个信号保留机制，即unpark在park之前执行了，这个park也不会让线程进入睡眠，因为消费者需要对生产者的每一个unpark都有响应，否则会有丢数据的风险。
但是unpark并不能叠加，所以unpark两次后，再Park两次还是会线程进入睡眠。&lt;/p&gt;
&lt;p&gt;条件变量一般是与mutex结合使用，传入同一个mutex，一个线程wait，一个线程notify。如果两个线程在操作同一个条件变量但是不同的mutex，会引起panic.&lt;/p&gt;
&lt;h1 id=&#34;atomic-and-memory-order&#34;&gt;Atomic and Memory order&lt;/h1&gt;
&lt;p&gt;原子类型可以在多线程间安全的访问和修改，但是依赖于Memory Ordering。比如最简单的order,Ralex,Relax只能保证单个变量的一致性，而多个变量间顺序无法保证。
atomic i32的溢出是回环的，不像普通的i32，溢出是会panic的。
为什么需要memory order?CPU会为了优化而把程序中的指令进行重排，写的是什么顺序，执行起来可能是别的顺序。
Happens before即保证A发生在B之前，但是在多线程中却是不一定的，使用锁可以保证，或者更严格的memory ordering。&lt;/p&gt;</description>
    </item>
    <item>
      <title>2024总结</title>
      <link>https://linxy.dev/posts/2024/</link>
      <pubDate>Mon, 30 Dec 2024 11:34:59 +0800</pubDate>
      <guid>https://linxy.dev/posts/2024/</guid>
      <description>&lt;p&gt;好久没有写过年度总结类的文章了，最大的原因是在年底回忆起来，一年可能什么也没做，实在不太好写；即使写出来也会是充满了悔恨的文字，颇有熬夜之后，临睡之前的悔恨之意。
扯远了，那么2024年做了些啥呢？&lt;/p&gt;
&lt;h2 id=&#34;运动&#34;&gt;运动&lt;/h2&gt;
&lt;p&gt;2024年最大的成功就是完成了两场半程马拉松，备赛时间从7月到10月底，刚好四个月。最好成绩是在杭州以1小时43分钟完赛。本来目标应该是跑进140的，但是在10月中的时候，一周无休的情况下，出去骑了100km，导致自己左脚踝受伤了，后面就只能停跑，到11月初参加比赛的时候，有氧水平掉了很多；杭州马拉松跑完的时候，脚真的是疼的不行，休息了一周硬顶上了南昌马拉松，以150完赛，当时感叹一下能完赛就算成功吧。&lt;br&gt;
在当前时间节点看来，备赛的4个月是我感觉状态最好的时候，睡眠质量好，吃的也多，爬山也很轻松。多运动确实有好处吧。骑车今年骑的不多了，因为秋天转跑步了，所以后面都只是穿插了一下骑行活动，但是今年依旧跑了1000公里，骑了2000公里。
25年的目标就是以330完赛全马吧，虽然现在一个比赛都没中过，也没开始备赛。&lt;/p&gt;
&lt;h2 id=&#34;书&#34;&gt;书&lt;/h2&gt;
&lt;p&gt;今年读了43本书，大多是推理小说与读库，还有一些文学类的，举几本印象深刻的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;《流俗地》，年初读的，读了之后就感叹道肯定是个人24年TOP1的书，文笔无可挑剔。也算是为我打了南洋文学的一扇门吧。&lt;/li&gt;
&lt;li&gt;《罪与罚》，年尾读的，读完后感觉陀爷真是神人，对杀人这件事的心理描写拿捏的如此精准，可见一定杀过人。&lt;/li&gt;
&lt;li&gt;《悉达多》，主角宛如圣人一般的寓言故事。&lt;/li&gt;
&lt;li&gt;《雾切7》，我们在群里多次提到了雾切，只能说这作的开篇和结尾确实花了心思，也是写的最好的。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;游戏&#34;&gt;游戏&lt;/h2&gt;
&lt;p&gt;今年唯一打完的单机游戏是baldr sky，好多游戏只打了个开篇就没有玩了。其中的原因是有些游戏后面是个悲剧，我不太愿意面对。有些是我人太浮躁，玩不太下去。开了很多游戏坑，还是得沉下心来好好体验这些游戏啊。
一句话总结就是上半年大多数时间在打雀魂，下半年跑步几乎不打游戏，12月在打CS。&lt;/p&gt;
&lt;h2 id=&#34;剧与动漫与电影&#34;&gt;剧与动漫与电影&lt;/h2&gt;
&lt;p&gt;今年看了不少剧，看的好电影也不少，提一些印象深刻的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;《我的天才女友》123季都看完了，第4季看了一半，前面123季拍的真很好，让我感觉老意大利真的美。&lt;/li&gt;
&lt;li&gt;《好东西》，算是年度好电影了吧，我看完的体验是到底谁在急眼呢，很多人都急眼了，感觉被攻击的是自己，可是电影中并没有攻击别人。电影更多的是表现女性生活，可以说并不止步女性的生活。&lt;/li&gt;
&lt;li&gt;《因果报应》，应该是我的年度悬疑电影吧。即便是印度电影，仍然体现的是女性主义的核心。&lt;/li&gt;
&lt;li&gt;《恶魔的破坏》，虽然还没有看完，但是值得我写一笔，动画体现的是日本的一种真实，而这些真实正在被消费，我感觉很诡异，但是实际上这种真实就是用来消费了，消费了才能有反馈啊。&lt;/li&gt;
&lt;li&gt;《异形》，retro风格的电影，镜头挺有讲究的，算是看的爽的一类电影。&lt;/li&gt;
&lt;li&gt;《JOJO5》，算是星尘十字军之后最好的一部吧，布姐的精神最好的诠释了黄金之风。&lt;/li&gt;
&lt;li&gt;《葬送的芙莉莲》，应该算我的年度动漫，制作好，音乐好听，周指活。&lt;/li&gt;
&lt;li&gt;《请回答1988》，18年开始看的，终于在今年看完了。几度看泪目了，时代与群像剧的TOP1吧。另外提一嘴《小巷人家》，本来能超越1988，可惜前8集能看。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;技术&#34;&gt;技术&lt;/h2&gt;
&lt;p&gt;今年尝试给Rust Analyzer提了几个PR，给apache下面的项目做了贡献，虽然都是些小小的，但是至少跨出了自己做开源的第一步，打破了自己心目中神化了提开源PR这么一件事的印象。其实大多数项目都一样，只是草台程度不同的区别。&lt;br&gt;
Rust方面读了Rust Atomic（这是本好书），然后拿Rust写了一个私活项目，可能也有几万行吧，算是实践的部分。另外这个项目还有客户端部分，写了一个月的avalonio，感觉写GUI体验真不太好，只能说GUI的editor跟游戏的editor都一样，真要做的好用，确实太难了。&lt;br&gt;
另外读了几本技术书，但是感觉都一般，就不提了。
可见25年还是得多写多读，不能再懈怠了。&lt;/p&gt;
&lt;h2 id=&#34;生活&#34;&gt;生活&lt;/h2&gt;
&lt;p&gt;今年9月买了一辆车，极大的扩大了行动的范围，虽然因为我们太宅，没有太出去走，但是至少多了一个出行的选择。&lt;br&gt;
家里三只猫，两只在年初的时候治好了病毒性口炎，也就年中的时候小猫肠胃炎去了一次医院，相对来说，猫仔的生活也算是很好了。&lt;br&gt;
去了一次胡彦斌的演唱会，爽听了三小时，也算是值回了票价了。&lt;br&gt;
去了一次初音的演唱会，体验了一下打call，虽然中文歌有点多，但是体验仍是不错的，可能这就是二次元吧。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;24年当时定下的目标其实很简单，就是走出舒适区，多去体验体验生活，现在来看，基本完成了目标了；体验了很多之前没有干过的事，看过不少自己以前没有看过的电影，剧的类型。
那么展望25年，25年的目标就是技术上精进一步，搞一个side project试试，游戏上打完海猫与BG3，十三机兵，阅读上一定要读完的是陀爷的书；运动上330完赛全马。&lt;/p&gt;</description>
    </item>
    <item>
      <title>终结这一切吧！Baldr Sky游玩感受</title>
      <link>https://linxy.dev/posts/baldr-sky/</link>
      <pubDate>Mon, 08 Jul 2024 18:45:38 +0800</pubDate>
      <guid>https://linxy.dev/posts/baldr-sky/</guid>
      <description>&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://linxy.dev/images/baldr_sky.png&#34;&gt;
去年这时候，&lt;a href=&#34;https://blog.mwish.me&#34;&gt;mwish&lt;/a&gt; 推荐给我一个galgame:Baldr Sky,我一直以来对galgame是不太感冒的，总感觉是与色色有关的游戏，而在游戏中寻找这种元素似乎是一件比较蠢的事；另外一个原因是，在我的认知中，一个黄油很难会有什么好的人物塑造，上来就推倒这种剧情显的很傻。而baldr sky是一个颠覆了我对galgame认知的作品，剧情音乐战斗都是超一流的优秀，而H的部分在这些看来真的很显的多余。&lt;/p&gt;
&lt;p&gt;蕾线&lt;br&gt;
作为开篇的线，本线做的非常好，玩家刚上手游戏，并不知道这个世界是怎么样的，而主人公甲在剧情中也是失忆状态的，所有的世界观与剧情都会随着记忆的恢复慢慢展开给玩家。不知道是不是故意而为之，制作组把蕾这样的一个人物放在最前面的，让后面的线推的时候，很难无视掉rain的付出，从而更加加深了对蕾的印象。蕾的人物塑造也非常鲜活，战场上给甲爷辅助，生活上给甲爷如同贤内助一般的照顾，可以说蕾是最完美的忠犬。在后面的线中，蕾无法作为女主出现在主流剧情中，但是仍然表现出来了对甲的忠诚，对甲隐藏的爱，这让我感觉非常的对不起她，难怪蕾是人气最高的角色。蕾线的Good ending是甲爷跟蕾远走高飞，过上了幸福的生活，可以说是非常甜的结局了，如果故事只限于此，而它将是平庸的作品。&lt;br&gt;
菜叶线&lt;br&gt;
菜叶线我印象最深的是结局中那个浪漫的场景，菜叶线紧接着蕾线，慢慢的把这个世界发生的事更加细化的展开来，让玩家发现这个世界不只是简单的一条故事线那么简单，总会有人死去。菜叶是一个非常可怜的女孩子，对老师充满了信任，最后却被利用了，不过我感觉这条线的情感有点牵强。在这条线中的千夏死掉了，从而引出了千夏线。&lt;br&gt;
千夏线&lt;br&gt;
我对千夏线只有愤怒，千夏塑造的非常好，学生时期的乐观与直球都是在隐藏自己，到后面发现了自己目标，哪怕让自己死也要达成目标。但是，这条线的甲爷塑造的太失败了，居然为了千夏大杀特杀，手刃蕾与魔狼的人，这对我来说简直不理喻，甲爷不是这样一个角色，为了爱情可以抛弃所有的人啊。千夏惨也是真的惨，千夏线她能得到幸福也是应该的。但是最后居然住到了Rain家里，这特么是什么鬼？还要在她家做。真是见鬼。&lt;br&gt;
亚季线&lt;br&gt;
我个人觉得亚季线真的是编剧写的最好的一条线，主要是在情感上被编剧牵着走，对于是不是乱伦这个问题，我感觉我的心情在过山车，而编剧用了好几层诡叙来震撼玩家。而亚季与情感线在我看来也比千夏与菜叶来的更加自然。&lt;br&gt;
真线&lt;br&gt;
真线其实我感觉更多的像是工具人线一般，因为情感上似乎也不是很能自恰，要说喜欢，我觉得真最多只是崇拜吧，而真因为一个恶作剧让自己承担上了无比沉重的责任，这样的写法让真这个角色更加有血有肉了。&lt;br&gt;
空线&lt;br&gt;
个人觉得空线其实写的挺一般，主要是文本量摆在那，但是要做的事情太多了，前面还要插进去一些救回各个女主，有些太过于冗长，如果更多的笔墨分到与空的情感交互上就更好了。不过空线作为收篇线，后半段非常的好，一个燃系机甲游戏，大甲收到各个世界线的甲的信念与记忆后，大喊Dr19，终结这一切吧后，BGM响起，与Dr19的战斗开始了，情感在这一刻到达了最顶峰，千千万万场战斗，最终都是为了救空，而空也独自撑了千万年。打完了Dr19后，我感觉到一丝解脱，终于结束了，终于救回了空。&lt;/p&gt;
&lt;p&gt;jihad与沉默之空的音乐也为本作增色许多，在与千夏的战斗中，响起了BGM之时，真是太带感了。&lt;br&gt;
战斗系统简约但不简单，也是到后期我才开发出一套连招可以输出很高，才在决战之时不那么痛苦，但是空线的战斗实在太多了，有些战斗真的又臭又长了。最后的True ending我也没有再打了，只能云一下了。&lt;/p&gt;
&lt;p&gt;长达69小时的游玩，只能说这游戏确实是神作。&lt;/p&gt;
&lt;p&gt;一些缺点：游戏不能放其它盘，容易闪退，而空线闪退频率太高了，好多战斗我都打了好多遍。&lt;/p&gt;
&lt;p&gt;个人喜好线：空线=亚季线=rain线 &amp;gt; 菜叶线 &amp;gt; 真线 &amp;gt; 千夏线&lt;br&gt;
个人女主喜好：蕾 = 空 &amp;gt; 千夏 &amp;gt; 亚季 &amp;gt; 真 &amp;gt; 菜叶。&lt;/p&gt;</description>
    </item>
    <item>
      <title>systemd-boot添加Windows引导项</title>
      <link>https://linxy.dev/posts/systemd-boot-windows/</link>
      <pubDate>Thu, 05 Oct 2023 23:51:52 +0800</pubDate>
      <guid>https://linxy.dev/posts/systemd-boot-windows/</guid>
      <description>&lt;h1 id=&#34;前言&#34;&gt;前言&lt;/h1&gt;
&lt;p&gt;最近把系统换成了CachyOS，用上了ZFS，这个发行版做的一些Tricky还是可以的，例如一些fish的脚本，还有软件与DE的自定义项都比较简洁，比ArcoLinux强上不少。&lt;br&gt;
我的情况是有两块NVMe的硬盘，一块是Windows系统，一块则是CachyOS。我的期望是用Linux Boot Manager去引导两个操作系统，比用Windows Boot Manager去引导Linux要好操作不少。&lt;/p&gt;</description>
    </item>
    <item>
      <title>raft extented论文笔记</title>
      <link>https://linxy.dev/posts/raft-notes/</link>
      <pubDate>Sun, 30 Aug 2020 13:34:56 +0800</pubDate>
      <guid>https://linxy.dev/posts/raft-notes/</guid>
      <description>&lt;h1 id=&#34;raft基础&#34;&gt;raft基础&lt;/h1&gt;
&lt;p&gt;一个raft集群一般来说有5个服务器结点，能让系统承受其中任意两台的down掉。每个服务器一共有三个状态，leader,follower,candidate,follower被动的接受来自candidate与leader的消息并作出回应。leader handle了所有了所有的客户端的请求，如果follower接收到了请求，会重定向到leader那去。&lt;/p&gt;
&lt;p&gt;raft把时间分成任意长的阶段，从选举开始，每个阶段都是一个连续增长的整数，至少有一个或者多个candidate会尝试成为leader。如果有一个candidate成为了leader，则接下来的term，它将是leader。在一些情况下，选举会出现，平分票数的情况，这种情况，term将会维持没有leader的状态到结束，到下一次的新的选举。&lt;/p&gt;
&lt;p&gt;不同的服务器 可能感知不到不同的term之间的转换，或者根本不知道有选举这回事，在这其中，term充当了一个逻辑时钟的作用，能让服务器能检测过时的信息，比如落后的leader。每一个服务器有一个current term number，随着时间增长，当服务器之间通信时，current term 会被 交换，如果有一个服务器的term小于别的，就会更新自己的，如果一个canditate或者leader发现它自己的term过时了，就会马上转变成follower，如果服务器收到了一个过时的请求，则会直接拒绝这个请求。&lt;/p&gt;
&lt;p&gt;raft的服务器之间用rpc请行通信，其中RequestVote用于canditate 来进行选举，AppendEntries 用于分发log与当心跳包（事实上是无论收到一个请求，都应该重置time out chekcer）。另外 还有一个转移快照的rpc。之后 再说。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h1 id=&#34;选举&#34;&gt;选举&lt;/h1&gt;
&lt;p&gt;raft使用心跳机制来触发选举。当服务器启动的时候，它们都是follower，follower在收到来自leader或者 candidate合法的rpc请求之前，一直是follower，leader会周期性的发送心跳包来保持leader的权威性，心跳包是一个空的AppendEntries，不带有Log entries。当一个follower一个election timeout后没有收到心跳包，则认为leader没了，将开始一轮选举，选出一个新的leader。&lt;/p&gt;
&lt;p&gt;为了开始一次选举，follower会给current term+1然后转变成candidate，然后投自己一票，然后同时发起RequestVote RPC给别的服务器。一个candidate会持续到以下三件情况出现，(a)它成了leader，(b)其它服务器成了leader(c)一段时间过去后，没有server成为leader。这将在之后讨论（应该是过一段时间重新发起）&lt;/p&gt;
&lt;p&gt;一个candidate如果收到了整个集群中大多数的投票 (with same term)，就会成为leader。每一个服务器最多只能投出一票。这个&lt;code&gt;大多数&lt;/code&gt; 的规则决定了，在一个term里，只能一个candidate成为leader。一旦candidate成为了leader，则会开始发送心跳包给其它所有的服务器，来保证自己的权威与阻止其它服务器发起选举。&lt;/p&gt;
&lt;p&gt;在投票的过程中，可能 会收到来其它服务器发来的AppendEntries RPC来声称自己是leader，这种情况，看leader的term与自己的current term的大小，如果比自己大，那别人就是leader，自己将退回到follower的状态，如果比自己小，就是拒绝别人的RPC call，并继续进行选举。&lt;/p&gt;
&lt;p&gt;一个选举如果选不出一个leader那就是分裂的选举，即没人得到大多数票，这种情况下，会等待超时直到下一次的选举，但是如果 没有做额外的操作，分裂的选举会不停的进行下去。&lt;/p&gt;
&lt;p&gt;raft采用了随机的选举超时来保证split vote是很少见的并且能快速的被解决。即每一个服务器的election timeout不一样，在重新发起选举的之前会等待这个timeout，timeout少的会先发起选举。一般的timeout会选择一个区间比如150-300ms之间。这样会有一个服务器超时完成并在别的服务器节点超时完成前完成选举。&lt;/p&gt;
&lt;h1 id=&#34;log-replication&#34;&gt;Log replication&lt;/h1&gt;
&lt;p&gt;一旦一个leader被选举，那它就开始接受client的请求，每一个client的请求都包含一个命令，这个命令会被 replicated state machines执行，leader将会把这个command append到日志中去，作为一个新的entry，然后用AppendEntries 分发到其它的服务器。 leader会永远的尝试去写入follower log entry，直到所有的log entry都被 写入。&lt;/p&gt;
&lt;p&gt;leader决定什么时候日志被 commit，当大多数的服务器都复制了一份entry后，就会提交，也会提前之前的entries，论文中设计了两个重要的属性&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果不同日志中的两个Entry有一样的index跟term，那他们存的一个东西&lt;/li&gt;
&lt;li&gt;如果不同日志中的两个entry有一样的index跟term，那他们之前的所有entry是相同的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;属性1保证了，在给定的term与index中只会创建一个entry，属性2保证了一致性的简单性。&lt;/p&gt;
&lt;p&gt;如果follower发现leader发过来的index跟term在自己的log里没有，那么会拒绝这个新的entry。（因为在消息中包含了这条新的之前的index跟term，所以可以检测之前的一致性，如果之前的都不一致就根本不会append这个新的）&lt;/p&gt;
&lt;p&gt;在Raft中，处理leader与follower的不一致性是通过强制把leader的log记录复制给follower来完成的，这意味着follower的log的冲突部分，会被完全覆盖。&lt;/p&gt;
&lt;p&gt;为了使follwer的log保持一致，leader必须找到leader与follwer最近的一个一样的entry，然后把这个之后的log都发给follower。&lt;/p&gt;
&lt;p&gt;leader对于每一个follower都维护了一个index，这个index是leader将要发给follower的下一个index，当一个leader上台后， 会把这个next index初始化为自己log中的最后一个index，如果有follower的记录与leader不一致，那么在下一次Append Entries RPC的一致性检查中失败。当这个调用失败后，leader将决定下一个next index是多少，最终，next index会在重试中到达leader与follower一致的地方。当RPC调用成功之后，leader会把之后的记录全发给follower，这样就follower就完成了与leader的一致性同步。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Rust Sized Trait与类型大小</title>
      <link>https://linxy.dev/posts/rust-sized-type/</link>
      <pubDate>Mon, 24 Aug 2020 11:25:32 +0800</pubDate>
      <guid>https://linxy.dev/posts/rust-sized-type/</guid>
      <description>&lt;p&gt;这篇文章来自于Github的一篇关于&lt;a href=&#34;https://github.com/pretzelhammer/rust-blog/blob/master/posts/sizedness-in-rust.md&#34;&gt;Rust size&lt;/a&gt;的一些介绍，本文内容基本上是这文章的总结。可以话尽量看原文。&lt;/p&gt;</description>
    </item>
    <item>
      <title>MIT 6.824 Lab1 mapreduce</title>
      <link>https://linxy.dev/posts/map-reduce/</link>
      <pubDate>Thu, 02 Jul 2020 13:42:38 +0800</pubDate>
      <guid>https://linxy.dev/posts/map-reduce/</guid>
      <description>&lt;h1 id=&#34;前言&#34;&gt;前言&lt;/h1&gt;
&lt;p&gt;MIT 6.824是著名的分布式课程，课程包含了视频，讲义，与作业。而本篇博文将阐述6.824课程的第一个作业的一些思考与解法，记录一些关于Map Reduce系统的思考。&lt;/p&gt;
&lt;h1 id=&#34;map-reduce&#34;&gt;Map Reduce&lt;/h1&gt;
&lt;p&gt;Map Reduce作为“谷三篇”的第一篇，出名不是没有原因的，jeff dean的超前思想构建了谷歌搜索的基石，使得谷歌在超大应用系统的构建上得心应手。而Map Reduce则是一个基石中的基石。&lt;/p&gt;
&lt;p&gt;Map Reduce的思想就是分布式的，系统中包含一个Master和许多个Worker，Master负责调度Worker与任务分发，容灾等等，Worker则与Master通信，请求任务。&lt;/p&gt;
&lt;p&gt;而Map Reduce则把一个任务拆分成Map与Reduce部分，简单来说，Map部分是把输入通过用户定义的Map Function输出成中间文件，再把中间文件作为输入给Reduce，Reduce把中间文件调用Reduce Function，然后合并并输出。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://linxy.dev/images/mapreduce.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;整个系统如图所示。如论文所说，这些文件可以是在本地机器上，也可以在分布式文件系统中，这并不影响整个系统框架。&lt;/p&gt;
&lt;p&gt;具体Map Reduce的思想可以读一下Google的论文。&lt;/p&gt;
&lt;h1 id=&#34;mit-6824-lab1&#34;&gt;MIT 6.824 Lab1&lt;/h1&gt;
&lt;p&gt;现代的6.824比以前的要难许多，我做过之前的lab1，当时就把Map Reduce的框架都搭好了，只要写两个函数就算通过了。而这个2020的6.824要求对Go熟悉且要把MapReduce整个实现一个大概出来，前后花了不少时间去思考要怎么来做这个实验。&lt;/p&gt;
&lt;h2 id=&#34;思考&#34;&gt;思考&lt;/h2&gt;
&lt;p&gt;当我们拿到Lab的时候需要做什么？需要思考我们要实现哪些东西。MIT的代码里只给了几个RPC的函数，然后在这个基础去实现Map Reduce。&lt;/p&gt;
&lt;p&gt;而我们要做的有：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;实现Master管理，这其中需要管理任务的状态，Worker请求任务的处理，Worker任务完成报告的处理，Worker失败超时的处理。&lt;/li&gt;
&lt;li&gt;实现Worker请求任务，对Map部分任务的处理，对Reduce部分任务的处理，还有任务完成的上报。&lt;/li&gt;
&lt;li&gt;还要实现一个文件锁，不能让Goroutine之间产生Race。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;实现&#34;&gt;实现&lt;/h2&gt;
&lt;p&gt;我的一些方案是在Master的结构体里管理两个Channel，当Master启动之后，把任务发给MapChannel，然后在另一个Goroutine里面对这个MapChannel进行读取，Channel如果不设置的话，一方没有读，写方会阻塞住，所以只有Worker进行请求任务之后才会继续生产任务。当Map部分完成后，再启动Reduce部分，生产Reduce任务到ReduceChannel。&lt;/p&gt;
&lt;p&gt;我们在每个请求任务的RPC返回之前再开启一个Goroutine来等待Worker的任务完成报告，这里我们用到了Go的select语法，并使用一个timer，如果超时就把这个任务再次Push进TaskChannel，即使任务失败了，也能再次把任务分发下去。&lt;/p&gt;
&lt;p&gt;对于Worker部分的代码来说，完全就是苦力活，可以看看官方代码里那个非分布式的Worker里代码，可以直接复制过来。Worker如果联系不上Master了，马上退出进程，这样就不用实现一个退出语义了。（其实是我不知道怎么让Master去通知Worker退出）&lt;/p&gt;
&lt;h2 id=&#34;代码&#34;&gt;代码&lt;/h2&gt;
&lt;p&gt;这里只给出一些结构体的定义：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Master:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Master&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MapTaskList&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MapTask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ReduceTaskList&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ReduceTask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MapTaskChan&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;chan&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MapTask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ReduceTaskChan&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;chan&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ReduceTask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;CompleteMapTaskNum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;CompleteReduceTaskNum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;mu&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Mutex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;files&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;nReduce&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Task Def&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
