2024年Go最全Golang Context 的并发安全性探究_golang context并发安全(1),2024Golang大厂面试集合

img
img
img

既有适合小白学习的零基础资料,也有适合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行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值