既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
func Worker(ctx context.Context) {
// 复制 ctx 的值到本地变量
localCtx := ctx
// 使用 localCtx 进行操作
}
通过将 Context 的值复制给本地变量,我们可以避免在操作 Context 时的竞争条件。
#### 2.3. 避免在子 goroutine 中创建和取消 Context
Context 的取消操作会导致所有依赖于该 Context 的子 Context 也被取消。因此,在子 goroutine 中创建和取消 Context 可能会产生意外的结果。
通常情况下,我们应该在主 goroutine 中创建根 Context,并在需要的时候将其传递给子 goroutine。子 goroutine 应该由主 goroutine 负责取消。
func Parent() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go Child(ctx)
}
func Child(ctx context.Context) {
// 使用 ctx 进行操作
}
#### 2.4. 使用 select 监听 Context 的取消
在使用 Context 进行并发操作时,通常还需要同时监听 Context 的取消事件。通过使用 select 语句,我们可以同时监听多个事件,包括 Context 的取消。
func SomeFunc(ctx context.Context) {
select {
case <-ctx.Done():
// Context 取消后的处理逻辑
case <-otherEventChan:
// 其他事件的处理逻辑
}
}
通过使用 select 语句,我们可以及时响应 Context 的取消事件,并执行相应的清理操作。
### 3. 案例
当使用 Golang Context 进行并发编程时,以下是三个示例案例,展示了如何正确使用 Context 并保证其在并发环境下的安全性。
#### 1. HTTP 请求超时处理
在进行 HTTP 请求时,我们经常需要设置超时时间并在超时时取消请求。使用 Context 可以很方便地实现这一点。
func HTTPRequestWithTimeout(ctx context.Context, url string) error {
client := http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
}
// 设置超时时间
timeoutCtx, cancel := context.WithTimeout(ctx, 5\*time.Second)
defer cancel()
req = req.WithContext(timeoutCtx)
// 发起 HTTP 请求
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
// 处理响应
// ...
return nil
}
通过使用 WithTimeout 函数创建一个带有超时时间的子 Context,我们可以实现在超时时取消 HTTP 请求。这样可以避免请求等待过长时间,同时确保并发执行多个请求时的安全性。
#### 2. 数据库事务管理
在并发访问数据库时,使用 Golang Context 可以有效地管理数据库事务,并在发生错误或上下文取消时回滚事务。
func DBTransaction(ctx context.Context, db *sql.DB) error {
tx, err := db.Begin()
if err != nil {
return err
}
// 将数据库连接封装到 Context 中
txCtx := context.WithValue(ctx, "db", tx)
// 在协程中运行业务逻辑
errCh := make(chan error)
go func() {
// 使用封装了数据库连接的 Context 进行操作
err := DoBusinessLogic(txCtx)
if err != nil {
errCh <- err
}
close(errCh)
}()
select {
case <-ctx.Done():
// 上下文被取消,回滚事务
tx.Rollback()
return ctx.Err()
case err := <-errCh:
// 业务逻辑发生错误,回滚事务
tx.Rollback()
return err
default:
// 业务逻辑正常完成,提交事务
err = tx.Commit()
if err != nil {
return err
}
return nil
}
}
![img](https://img-blog.csdnimg.cn/img_convert/e422c58a1b9a001ae1d49395f18bd3bc.png)
![img](https://img-blog.csdnimg.cn/img_convert/0e7800185d4e4a6753380efe3f713b18.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**