• 保存到桌面加入收藏设为首页
Linux

Linux命名空间和开始混合

时间:2018-08-13 19:34:42   作者:368zixun   来源:   阅读:433   评论:0
内容摘要:在这篇博文中,我们将跟进“Linux命名空间和Go Do not Mix”帖子,我们将在最近的Go 1.10版本中展示前一篇文章中提到的问题是如何解决的。问题回顾一下,主要问题是Go运行时不允许我们安全地更改OS线程的本地状态(Go符号中的“M”)调度goroutine,即使该线......

在这篇博文中,我们将跟进“Linux命名空间和Go Do not Mix”帖子,我们将在最近的Go 1.10版本中展示前一篇文章中提到的问题是如何解决的

问题

回顾一下,主要问题是Go运行时不允许我们安全地更改OS线程的本地状态(Go符号中的“M”)调度goroutine,即使该线程已被锁定  runtime.LockOSThread

运行时可以使用具有已修改状态的线程来创建将继承状态的新线程,并且新线程可能会运行任何其他goroutine,从而导致意外行为。

因此,在我们的例子中,我们无法安全地从goroutine更改网络名称空间。Weave Net中通过Netlink配置或列出容器网络接口时,这一点至关重要

固定

幸运的是,该帖子引发了一些讨论,最终导致对Go运行时的一些相关修复:

  • #20676:不会从当前锁定的线程创建新线程   runtime.LockOSThread

  • #20395:如果goroutine在退出之前未解锁,则锁定的线程不会被重新用于安排其他goroutine。

  • #20458:如果线程被多次锁定,  runtime.UnlockOSThread 则必须调用相同的次数才能解锁线程。

所有修复程序都已随Go 1.10一起发布,您可以// +build go1.10在代码中使用约束来要求最小版本的Go来编译它。

最后,我们可以摆脱Weave Net 的丑陋黑客,它曾经创建一个单独的操作系统进程,只是为了在给定的网络命名空间中执行Go函数。

陷阱

这一切看起来都很棒。然而,有一个问题:runtime.LockOSThread不一定会在同一个线程上运行一个被锁定的新goroutine。

要说明此行为,请考虑以下示例:

package main
import (
 "fmt"
 "runtime"
 "github.com/vishvananda/netns"
)
func main() {
 ns, err := netns.New()
 panicOnErr(err)
 runtime.LockOSThread()
 defer runtime.UnlockOSThread()
 err = netns.Set(ns)
 panicOnErr(err)
 parentNetNS, err := netns.Get()
 panicOnErr(err)
 fmt.Println("parent:", parentNetNS)
 wait := make(chan struct{})
 go func() {
 childNetNS, err := netns.Get()
 panicOnErr(err)
 fmt.Println("child:", childNetNS)
 wait <- struct{}{}
 }()
 <-wait
}
func panicOnErr(err error) {
 if err != nil {
 panic(err)
 }
}

示例程序的输出:

parent: NS(4: 3, 4026532486)
child: NS(5: 3, 4026531993) 


正如您所看到的,子goroutine最终运行在与父节点不同的网络命名空间中(输出中每行的最后一个数字是网络命名空间的inode)。

因此,如果期望新的goroutine在同一个线程或具有相同修改状态的线程上运行则不要从锁定的goroutine中生成新的goroutine。从锁定的goroutine调用某些库代码时,这可能会成为一个问题,因为开发人员可能不知道库是否在内部产生了goroutine。检测这种不安全的病例可能是静态分析的主题(提示:相对较低的悬挂果实)。

另一件需要考虑的事情是在退出锁定的goroutine而不解锁它时可能会出现性能损失。在这种情况下,运行时可能会创建一个用于调度goroutine的新线程,这会阻止某些CPU周期执行有用的工作。因此,如果您努力提高性能,请不要忘记撤消对线程状态的更改并将其解锁,以便运行时可以重用它。

结论

Go 1.10引入了修复程序,使其更适合于了解底层操作系统的编程系统。然而,从锁定的产生goroutine需要非常小心。


标签:Linux命名空间和开始混合  
相关评论
中国互联网举报中心 网络违法举报中心 垃圾信息举报中心


声明:本网站内容摘抄自互联网,倘若侵犯您的版权请联系我们点这里给我发消息

  黔ICP备16010319号-3  
360安全检测 凭安信用认证 upyun网站联盟 腾讯云安全认证

Powered by OTCMS V3.61