<?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>Go on Sirius&#39; Blog</title>
    <link>https://sirius2alpha.github.io/tags/go/</link>
    <description>Recent content in Go on Sirius&#39; Blog</description>
    <image>
      <title>Sirius&#39; Blog</title>
      <url>https://sirius2alpha.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</url>
      <link>https://sirius2alpha.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</link>
    </image>
    <generator>Hugo -- 0.127.0</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 26 Jul 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://sirius2alpha.github.io/tags/go/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>【go的源码阅读】context的实现：context.go</title>
      <link>https://sirius2alpha.github.io/posts/notes/2-areas/%E6%8A%80%E6%9C%AF%E6%A0%88/go/go-context/</link>
      <pubDate>Fri, 26 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://sirius2alpha.github.io/posts/notes/2-areas/%E6%8A%80%E6%9C%AF%E6%A0%88/go/go-context/</guid>
      <description>理解Context 这篇文章介绍的很清楚：深入理解Go Context
这个比较详细，但是层次不好：理解GO CONTEXT机制
关于context的使用场景 context的主要使用场景在于：一个任务在处理的过程中可能会启动很多个协程来进行处理。在这个过程中，如果上游的任务想要取消，下游的任务也应当一起取消。context的任务就来了。
内容介绍 context包的内容可以概括为：1个接口，4个实现，6个方法
接口 context.Context 一个接口是指：context.Context
type Context interface { Deadline() (deadline time.Time, ok bool) Done() &amp;lt;-chan struct{} Err() error Value(key interface{}) interface{} } Deadline( ) Deadline会返回一个超时时间，Goroutine获得了超时时间后，例如可以对某些io操作设定超时时间。
函数签名 Deadline() (deadline time.Time, ok bool)
Deadline 返回的时间 deadline time.Time 代表这个ctx应该被取消的时间。返回的 ok 如果是 false 表示这个context没有设置deadline。连续调用 Deadline 会返回相同的结果。
// Deadline returns the time when work done on behalf of this context // should be canceled. Deadline returns ok==false when no deadline is // set.</description>
    </item>
    <item>
      <title>golang八股文</title>
      <link>https://sirius2alpha.github.io/posts/notes/4-archive/%E6%B1%82%E8%81%8C%E5%BD%92%E6%A1%A3/go8/</link>
      <pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://sirius2alpha.github.io/posts/notes/4-archive/%E6%B1%82%E8%81%8C%E5%BD%92%E6%A1%A3/go8/</guid>
      <description>Golang goroutine内存泄漏 slice导致
获取长字符串中的一段，导致字符串未释放；
获取长slice中的一段导致长slice未释放；
在长切片中新建sllice导致泄漏
channel导致
发送不接受，接收不发送，nil channel
从 channel 里读，但是同时没有写入操作 向 无缓冲 channel 里写，但是同时没有读操作 向已满的 有缓冲 channel 里写，但是同时没有读操作 select操作在所有case上都阻塞() goroutine进入死循环，一直结束不了 向 nil channel 发送和接收数据都将会导致阻塞。这种情况可能在我们定义 channel 时忘记初始化的时候发生。 可见，很多都是因为channel使用不当造成阻塞，从而导致goroutine也一直阻塞无法退出导致的。
传统同步方式sync.mutex，sync.waitgroup导致
用了mutex加lock之后忘记unlock；
在一开始设置了具体数目的wg.wait(n)，但是有没有写够足够数量n的wg.Done()，导致wg.Wait()一直等待下去。（正确方式可以使用wg.Add(1)配合wg.Done使用）
Go调度器的GMP 在Go语言中，GPM通常指的是Goroutine、Processor和Machine，这是Go调度器（scheduler）的核心组成部分。下面是对每个部分的详细介绍：
Goroutine (G):
Goroutine是Go语言中的轻量级线程，由Go运行时管理。它们是并发的基本单位，可以被创建和销毁，而无需操作系统级别的线程开销。Goroutine的创建和销毁非常快速，因此可以轻松地创建成千上万个Goroutine。 Goroutine的调度是协作式的，这意味着一个Goroutine在执行时会自愿放弃CPU，让其他Goroutine有机会执行。这种协作式调度使得Go语言能够高效地利用多核处理器。 Processor (P):
Processor是Go调度器中的一个抽象概念，代表一个逻辑处理器。每个P都有一个本地运行队列，用于存储待执行的Goroutine。P的数量可以通过环境变量或运行时设置来调整，通常设置为CPU的核心数。 P的主要作用是管理Goroutine的执行。当一个Goroutine被调度到P上时，P会将其分配给一个可用的Machine（M）来执行。 Machine (M):
Machine代表一个操作系统线程。M与P关联，负责执行Goroutine。一个M可以与多个P关联，但在任何给定时间，一个M只能执行一个P的Goroutine。 M的主要作用是执行Goroutine的代码。当一个Goroutine被调度到M上时，M会执行该Goroutine的代码，直到该Goroutine自愿放弃CPU或被抢占。 Go调度器的工作原理是将Goroutine（G）分配到Processor（P）上，然后由Machine（M）执行。这种设计使得Go语言能够高效地利用多核处理器，并实现高并发。
在 Go 语言的运行时系统中，Goroutine（简称 G）有多种状态，用于描述它在不同时间点的执行情况。这些状态在 Go 的调度器（GMP 模型）中扮演重要角色。GMP 模型由 Goroutine（G）、工作线程（M）和处理器（P）三部分组成。以下是 G 的主要状态及其转变过程，以及它们与 GMP 模型的关系。
G 的状态 _Gidle：空闲状态。Goroutine 尚未被使用或已经完成执行，等待被分配新任务。 _Grunnable：可运行状态。Goroutine 已经准备好运行，等待被调度器选中运行。 _Grunning：运行状态。Goroutine 正在运行中。 _Gsyscall：系统调用状态。Goroutine 正在执行系统调用，处于阻塞状态，不会被调度器调度。 _Gwaiting：等待状态。Goroutine 在等待某个条件（例如通道操作、定时器、网络 I/O 等）完成。 _Gdead：死亡状态。Goroutine 已经完成执行，无法再被重新使用。 _Gcopystack：堆栈复制状态。Goroutine 的堆栈正在被复制，以调整其大小。 状态转变及其与 GMP 的关系 创建 Goroutine _Gidle -&amp;gt; _Grunnable 创建一个新的 Goroutine，并将其状态设置为 _Grunnable，表示该 Goroutine 准备好运行。 由 P 将新的 Goroutine 添加到其本地运行队列或全局运行队列中。 g := newGoroutine() g.</description>
    </item>
    <item>
      <title>【go的源码阅读】channel的实现：chan.go</title>
      <link>https://sirius2alpha.github.io/posts/notes/2-areas/%E6%8A%80%E6%9C%AF%E6%A0%88/go/go-channel/</link>
      <pubDate>Fri, 10 May 2024 00:00:00 +0000</pubDate>
      <guid>https://sirius2alpha.github.io/posts/notes/2-areas/%E6%8A%80%E6%9C%AF%E6%A0%88/go/go-channel/</guid>
      <description>channel的简单使用 在Go语言中，通道（channel）是一种用于在goroutine之间进行通信和同步的机制。下面是一些简单的通道使用示例，以及它们对应的底层函数调用。
package main import ( &amp;#34;fmt&amp;#34; &amp;#34;time&amp;#34; ) func main() { ch := make(chan int) // 创建通道 go func() { ch &amp;lt;- 42 // 发送数据到通道 }() go func() { value := &amp;lt;-ch // 从通道接收数据 fmt.Println(&amp;#34;Received:&amp;#34;, value) }() time.Sleep(1 * time.Second) // 等待goroutine完成 close(ch) // 关闭通道 } 底层函数调用 创建通道：
ch := make(chan int) 底层调用：
makechan(elemtype, size) 发送数据到通道：
ch &amp;lt;- 42 底层调用：
chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool 从通道接收数据：</description>
    </item>
    <item>
      <title>点击排行榜scoreboard</title>
      <link>https://sirius2alpha.github.io/posts/notes/4-archive/%E9%A1%B9%E7%9B%AE%E5%BD%92%E6%A1%A3/aorb/dev-scoreboard/</link>
      <pubDate>Sun, 21 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://sirius2alpha.github.io/posts/notes/4-archive/%E9%A1%B9%E7%9B%AE%E5%BD%92%E6%A1%A3/aorb/dev-scoreboard/</guid>
      <description>本文记录使用vue&#43;gin&#43;redis搭建了一个简单的点击排行榜，虽然有点无聊，但是两个幼稚鬼玩好好笑hhh</description>
    </item>
    <item>
      <title>Go学习笔记</title>
      <link>https://sirius2alpha.github.io/posts/notes/4-archive/%E5%AD%A6%E4%B8%9A%E5%BD%92%E6%A1%A3/note-go/</link>
      <pubDate>Tue, 20 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://sirius2alpha.github.io/posts/notes/4-archive/%E5%AD%A6%E4%B8%9A%E5%BD%92%E6%A1%A3/note-go/</guid>
      <description>配置 Go 工作区 继续之前，请务必仔细阅读此部分。
Go 在组织项目文件方面与其他编程语言不同。 首先，Go 是在工作区的概念下工作的。 工作区就是应用程序源代码所在的位置。 所有 Go 项目共享同一个工作区。 不过，从版本 1.11 开始，Go 已开始更改此方法。 你尚且不必担心，因为我们将在下一个模块中介绍工作区。 现在，Go 工作区位于 $HOME/go，但如果需要，可以为所有项目设置其他位置。
若要将工作区设置为其他位置，可以使用 $GOPATH 环境变量。 在处理更复杂的项目时，此环境变量有助于避免将来出现问题。
Go 工作区文件夹 每个 Go 工作区都包含三个基本文件夹：
bin：包含应用程序中的可执行文件。 src：包括位于工作站中的所有应用程序源代码。 pkg：包含可用库的已编译版本。 编译器可以链接这些库，而无需重新编译它们。 例如，工作站文件夹结构树可能与下面的示例类似：
bin/ hello coolapp pkg/ github.com/gorilla/ mux.a src/ github.com/golang/example/ .git/ hello/ hello.go
Go实战经验 在命令行中输入&amp;rsquo;code . &amp;lsquo;会唤起VS code编辑当前目录
源码规范 可执行文件都要包含在package main中 import的包必须都要使用，否则报错不进行编译；vs code中保存文件就会自动调整文件格式，并且删除未使用的import 整个package main中只能有一个func main() 变量的声明和初始化 Go是强类型语言，声明的每个变量都绑定到特定的数据类型，并且只接受与此类型匹配的值。
变量声明的方式有很多，格式和其他语言不太一样
最普通的方式：var 变量名称 变量类型 Go也可以像Python那样自动推断变量的类型，有些时候可以不用加类型名称 最常用的方式（只适用于在函数内，声明并初始化一个新的变量）：使用冒号等号 age := 32 注意，在函数体外还是只能用var的方式声明和初始化变量 // 变量声明 // 变量声明了必须要使用，否则编译不通过 var first string var second, third string var age int = 1 var ( fisrtly int = 1 secondly string = 2 thirdly = &amp;#34;123&amp;#34; ) var firstName, secondName, agenumber = &amp;#34;123&amp;#34;, &amp;#34;456&amp;#34;, 32 // 最常见的声明方式 冒号等于号 := 用于声明并初始化变量，不能用于常量的声明 firstName_, secondName_, age_ := &amp;#34;123&amp;#34;, &amp;#34;456&amp;#34;, 32 // 常量声明f const HTTPstatusOK = 200 const ( StatusOK = 0 StatusConnectionReset = 1 StatusOtherError = 2 ) 数据类型 基本类型：数字、字符串、布尔值 聚合类型：数组、结构体 引用类型：指针、切片、映射、函数、通道 接口类型：接口 基本类型 在 Go 中，如果你不对变量初始化，所有数据类型都有默认值。</description>
    </item>
  </channel>
</rss>
