13

MIT 6.824 分布式系统课程第五课:Go线程和Raft - Jeffery的博客 | Jeffery Blog

 4 years ago
source link: https://blog.microdba.com/%E5%88%86%E5%B8%83%E5%BC%8F%E7%B3%BB%E7%BB%9F/2020/04/03/mit-6.824-lecture-5-go-thread-and-raft/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

MIT 6.824 分布式系统课程第五课:Go线程和Raft

笔记:Lecture 5: Go, Threads, and Raft

视频:Lecture 5: Go, Threads, and Raft

论文地址:The design of a practical system for fault-tolerant virtual machines

课程概要

Go语言内存模型、并发原语、并发模式、调试

正文内容

Go内存模型这篇文章讲述go语言中的内存模型,它告诉我们如何写出正确的多线程代码。goroutines和并发在go中有着千丝万缕的关系,性能、便捷性。经过语言的不断迭代,goroutines的性能也得到极大的提升。本课的重点在于如何写正确的并发代码,而不是性能。

“write correct code”.

Goroutines,闭包

goroutines是轻量级线程,彼此并发运行。当main goroutine退出时,程序自动终止,与此同时程序运行的其他goroutines也会终止运行。

闭包:标示符捕获,gotchas绑定

  • closure.go:go中拥有头等函数,配合goroutines使用。对变量的作用域进行限制,让声明的函数只作用域闭包内部。
  • loop.go:循环创建goroutine(输出结果不一定按顺序输出,因为并发,并非同步执行)
  • bad.go:变量i访问的是gorountine外部变量,每个goroutine访问时的结果都不确定,受外部循环执行快慢的影响。

Time

  • sleep.go:time.Now()、time.Sleep()
  • sleep-cancel.go:不要写无限循环的代码。使用锁时要小心死锁。函数返回(return)前需要释放锁

Mutexes:互斥量

  • bad.go
  • basic.go:基本使用defer
  • per-field.go:锁保护是保护变量,不是保护访问共享数据。锁的目的是为了在访问或者是修改变量时,只有单个线程在操作。其结果不受其他线程的影响。所以转账的增和减应在同一个锁里面。

    关键:临时暂停其他线程的修改、unlock解锁访问。没有其他线程打断访问

    锁:确保lock()与unlock之间的代码执行的原子性,防止竞争访问或者修改

  • bank.go:银行转账问题

条件变量

  • 等待(wait)、信号(signal)、广播(broadcast)
  • vote-count-1.go ….vote-count-4.go
  • cond.txt,如何避免竞争条件。
    • 使用循环检查条件状态,也可以使用条件变量sync.Cond
    • 锁应避免在会导致CPU100%的代码段中使用

Channel:通道

  • 类似同步队列原语
  • producor-consumer.go 生产消费者模型
  • wait等待前置调用完成
  • unbuffered.go:未初始化长度的通道,同步
  • deadlock.go:死锁

Debugging:调试

  • 在Raft目录下可以使用util.go中的DPrintf调试,输出日志
  • 使用-race帮助识别数据竞争
    • go test -race -run 2A
    • not a proof
    • race不是万能的,不是所有的竞争数据情况都能识别到
  • SIGQUIT
    • SIGQUIT默认监听所有的goroutines.并打印栈
    • Ctrl+\可以发送SIGQUIT到当前进程
  • 处理goroutines溢出
    • 使用ps命令查看运行的进程
    • 发送SIGQUIT或者是SIGKILL信号给进程:kill -QUIT pid 或 kill -KILL pid
  • 并行

常用工具

  • 使用man命令查看工具使用的手册
  • 或者使用tldr命令快速的查看手册:tldr.sh
  • 重定向输出
    • stdout输出正常结果
    • stderr输出错误结果
    • >&>
      • 重定向输出结果到文件,错误会接着显示
      • & 错误和标准输出都写入到文件
    • tee、通道||&
      • tee重定向输出到文件并显示
      • echo "example" | tee FILE
      • 使用|&可以重定向标准输出和错误
  • 文件阅读
    • head、tail、less
    • grep
      • -i不区分大小写
      • -n显示行号
      • grep -in searchString file
    • ripgrep Ripgrep
      • 和grep类似,但支持整个目录

参考资料



About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK