博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go并发编程实战 (郝林 著)
阅读量:6902 次
发布时间:2019-06-27

本文共 16369 字,大约阅读时间需要 54 分钟。

第1章 初识Go语言

  1.1 语言特性

  1.2 安装和设置

  1.3 工程构造

    1.3.1 工作区

    1.3.2 GOPATH

    1.3.3 源码文件

package mainimport (    "fmt"    "runtime")var m = map[int]string{
1:"A",2:"B",3:"C"}var info stringfunc init() { fmt.Printf("Init :: Map: %v\n",m) info = fmt.Sprintf("OS: %s,Arch: %s",runtime.GOOS,runtime.GOARCH)}func main() { fmt.Printf("main :: %s",info)}
pkg_init

    1.3.4 代码包

  1.4 标准命令简述

  1.5 问候程序

package mainimport (    "bufio"    "os"    "fmt")func main() {    inputReader := bufio.NewReader(os.Stdin)    fmt.Println("Please input your name:")    input,err := inputReader.ReadString('\n')    if err != nil {        fmt.Printf("Found an error : %s\n",err)    } else {        input = input[:len(input)-1]        fmt.Printf("Hello,%s!\n",input)    }}
hello

  1.6 小结

第2章 语法概述

  2.1 基本构成要素

    2.1.1 标识符

    2.1.2 关键字

    2.1.3 字面量

    2.1.4 操作符

    2.1.5 表达式

  2.2 基本类型

  2.3 高级类型

    2.3.1 数组

    2.3.2 切片

    2.3.3 字典

    2.3.4 函数和方法

    2.3.5 接口

    2.3.6 结构体

  2.4 流程控制

    2.4.1 代码块和作用域

package mainimport "fmt"var v = "1,2,3"func main() {    v := []int{
1,2,3} if v != nil { var v = 123 fmt.Printf("%v\n",v) }}
redeclare

    2.4.2 if语句

    2.4.3 switch语句

    2.4.4 for语句

    2.4.5 defer语句

    2.4.6 panic和recover

  2.5 聊天机器人

package mainimport (    "bufio"    "os"    "fmt"    "strings")func main() {    inputReader := bufio.NewReader(os.Stdin)    fmt.Println("Please input your name:")    input,err := inputReader.ReadString('\n')    if err != nil {        fmt.Printf("An error occurred: %s\n",err)        os.Exit(1)    } else {        name := input[:len(input)-1]        fmt.Printf("Hello, %s! What can I do for you?\n",name)    }    for {        input,err = inputReader.ReadString('\n')        if err != nil {            fmt.Printf("An error occurred: %s\n",err)            continue        }        input = input[:len(input)-1]        input = strings.ToLower(input)        switch input {        case "":            continue        case "nothing","bye":            fmt.Println("Bye!")            os.Exit(0)        default:            fmt.Println("Sorry,I didn't catch you.")        }    }}
simple

  2.6 小结

第3章 并发编程综述

  3.1 并发编程基础

    3.1.1 串行程序与并发程序

    3.1.2 并发程序与并行程序

    3.1.3 并发程序与并发系统

    3.1.4 并发程序的不确定性

    3.1.5 并发程序内部的交互

  3.2 多进程编程

    3.2.1 进程

    3.2.2 关于同步

    3.2.3 管道

    3.2.4 信号

    3.2.5 socket

  3.3 多线程编程

    3.3.1 线程

    3.3.2 线程的同步

  3.4 多线程与多进程

  3.5 多核时代的并发编程

  3.6 小结

第4章 Go的并发机制

  4.1 原理探究

    4.1.1 线程实现模型

    4.1.2 调度器

    4.1.3 更多细节

  4.2 goroutine

    4.2.1 go语句与goroutine

package mainfunc main() {    go println("Go!Goroutine!")}
gobase1
package mainimport "time"func main() {    go println("Go! Goroutine!")    time.Sleep(time.Millisecond)}
gobase2
package mainimport (    "fmt"    "time")func main() {    name := "Eric"    go func() {        fmt.Printf("Hello,%s!\n",name)    }()    name = "Harry"    time.Sleep(time.Millisecond)}
gobase3
package mainimport (    "fmt"    "time")func main() {    names := []string{
"Eric","Harry","Robert","Jim","Mark"} for _,name := range names { go func() { fmt.Printf("Hello,%s\n",name) }() } time.Sleep(time.Millisecond)}
gobase4
package mainimport (    "fmt"    "time")func main() {    names := []string{
"Eric","Harry","Robert","Jim","Mark"} for _,name := range names { go func(who string) { fmt.Printf("Hello,%s\n",who) }(name) } time.Sleep(time.Millisecond)}
gobase5

    4.2.2 主goroutine的运作

    4.2.3 runtime包与goroutine

  4.3 channel

    4.3.1 channel的基本概念

package mainimport (    "fmt"    "time")var strChan = make(chan string,3)func main() {    syncChan1 := make(chan struct{},1)    syncChan2 := make(chan struct{},2)    go func() {        <-syncChan1        fmt.Println("Received a sync signal and wait a second... [receiver]")        time.Sleep(time.Second)        for {            if elem,ok := <- strChan;ok {                fmt.Println("Received:",elem,"[receiver]")            } else {                break            }        }        fmt.Println("Stopped. [receiver]")        syncChan2 <- struct{}{}    }()    go func() {        for _,elem := range []string{
"a","b","c","d"} { strChan <- elem fmt.Println("Sent:",elem,"[sender]") if elem == "c" { syncChan1 <- struct{}{} fmt.Println("Sent a sync signal. [Sender]") } } fmt.Println("Wait 2 seconds... [sender]") time.Sleep(time.Second * 2) close(strChan) syncChan2 <- struct{}{} }() <-syncChan2 <-syncChan2}
chanbase1
package mainimport (    "fmt"    "time")var mapChan = make(chan map[string]int,1)func main() {    syncChan := make(chan struct{},2)    go func() {        for {            if elem,ok := <- mapChan;ok {                elem["count"]++            } else {                break            }        }        fmt.Println("Stopped. [receiver]")        syncChan <- struct{}{}    }()    go func() {        countMap := make(map[string]int)        for i := 0; i < 5; i++ {            mapChan <- countMap            time.Sleep(time.Millisecond)            fmt.Printf("The count map: %v. [sender]\n",countMap)        }        close(mapChan)        syncChan <- struct{}{}    }()    <-syncChan    <-syncChan}
chanval1
package mainimport (    "fmt"    "time")type Counter struct {    count int}var mapChan = make(chan map[string]Counter,1)func main() {    syncChan := make(chan struct{},2)    go func() {        for {            if elem,ok := <- mapChan;ok {                counter := elem["count"]                counter.count++            } else {                break            }        }        fmt.Println("Stopped. [receiver]")        syncChan <- struct{}{}    }()    go func() {        countMap := map[string]Counter {            "count": Counter{},        }        for i := 0; i < 5; i++ {            mapChan <- countMap            time.Sleep(time.Millisecond)            fmt.Printf("The count map: %v. [sender]\n",countMap)        }        close(mapChan)        syncChan <- struct{}{}    }()    <- syncChan    <- syncChan}
chanval2
package mainimport "fmt"func main() {    dataChan := make(chan int,5)    syncChan1 := make(chan struct{},1)    syncChan2 := make(chan struct{},2)    go func() {        <- syncChan1        for {            if elem,ok := <- dataChan;ok {                fmt.Println("Received: %d [receiver]\n",elem)            } else {                break            }        }        fmt.Println("Done. [receiver]")        syncChan2 <- struct{}{}    }()    go func() {        for i := 0; i < 5; i++ {            dataChan <- i            fmt.Printf("Sent: %d [sender]\n",i)        }        close(dataChan)        syncChan1 <- struct{}{}        fmt.Println("Done. [sender]")        syncChan2 <- struct{}{}    }()    <- syncChan2    <- syncChan2}
chanclose

       4.3.2 单向channel

package mainimport (    "fmt"    "time")var strChan = make(chan string,3)func main() {    syncChan1 := make(chan struct{},1)    syncChan2 := make(chan struct{},2)    go receive(strChan,syncChan1,syncChan2)    go send(strChan,syncChan1,syncChan2)    <- syncChan2    <- syncChan2}func send(strChan chan<- string,syncChan1 chan<- struct{},syncChan2 chan<- struct{}) {    for _,elem := range []string{
"a","b","c","d"} { strChan <- elem fmt.Println("Sent:",elem,"[sender]") if elem == "c" { syncChan1 <- struct{}{} fmt.Println("Sent a sync signal. [sender]") } } fmt.Println("Wait 2 seconds... [sender]") time.Sleep(time.Second * 2) close(strChan) syncChan2 <- struct{}{}}func receive(strChan <-chan string,syncChan1 <-chan struct{},syncChan2 chan<- struct{}) { <- syncChan1 fmt.Println("Received a sync signal and wait a second... [receiver]") time.Sleep(time.Second) for { if elem,ok := <- strChan;ok { fmt.Println("Received:",elem,"[receiver]") } else { break } } fmt.Println("Stopped. [receiver]") syncChan2 <- struct{}{}}
chanbase2
package mainimport "fmt"func main() {    var ok bool    ch := make(chan int,1)    _,ok = interface{}(ch).(<-chan int)    fmt.Println("chan int => <-chan int:",ok)    _,ok = interface{}(ch).(chan<- int)    fmt.Println("chan int => chan<- int:",ok)    sch := make(chan<- int,1)    _,ok = interface{}(sch).(chan int)    fmt.Println("chan<- int => chan int:",ok)    rch := make(<-chan int,1)    _,ok = interface{}(rch).(chan int)    fmt.Println("<-chan int => chan int:",ok)}
chanconv

    4.3.3 for语句与channel

package mainimport (    "fmt"    "time")var strChan = make(chan string,3)func main() {    syncChan1 := make(chan struct{},1)    syncChan2 := make(chan struct{},2)    go receive(strChan,syncChan1,syncChan2)    go send(strChan,syncChan1,syncChan2)    <-syncChan2    <-syncChan2}func receive(strChan <-chan string,syncChan1 <-chan struct{},syncChan2 chan<- struct{}) {    <-syncChan1    fmt.Println("Received a sync signal and wait a second... [receiver]")    time.Sleep(time.Second)    for elem := range strChan {        fmt.Println("Received:",elem,"[receiver]")    }    fmt.Println("Stopped. [receiver]")    syncChan2 <- struct{}{}}func send(strChan chan<- string,syncChan1 chan<- struct{},syncChan2 chan<- struct{}) {    for _,elem := range []string{
"a","b","c","d"} { strChan <- elem fmt.Println("Sent:",elem,"[sender]") if elem == "c" { syncChan1 <- struct{}{} fmt.Println("Sent a sync signal. [sender]") } } fmt.Println("Wait 2 seconds... [sender]") time.Sleep(time.Second * 2) close(strChan) syncChan2 <- struct{}{}}
chanbase3

    4.3.4 select语句

package mainimport "fmt"var intChan1 chan intvar intChan2 chan intvar channels = []chan int{intChan1,intChan2}var numbers = []int{
1,2,3,4,5}func main() { select { case getChan(0) <- getNumber(0): fmt.Println("1th case is selected.") case getChan(1) <- getNumber(1): fmt.Println("The 2nd case is selected.") default: fmt.Println("Default") }}func getNumber(i int) int { fmt.Printf("numbers[%d]\n",i) return numbers[i]}func getChan(i int) chan int { fmt.Printf("channel[%d]\n",i) return channels[i]}
selecteval
package mainimport "fmt"func main() {    chanCap := 5    intChan := make(chan int,chanCap)    for i := 0; i < chanCap; i++ {        select {        case intChan <- 1:        case intChan <- 2:        case intChan <- 3:        }    }    for i := 0; i < chanCap; i++ {        fmt.Printf("%d\n",<-intChan)    }}
selectrandom
package mainimport "fmt"func main() {    intChan := make(chan int,10)    for i := 0; i < 10; i++ {        intChan <- 1    }    close(intChan)    syncChan := make(chan struct{},1)    go func() {    Loop:        for {            select {            case e,ok := <-intChan:                if !ok {                    fmt.Println("End.")                    break Loop                }                fmt.Printf("Received: %v\n",e)            }        }        syncChan <- struct{}{}    }()    <-syncChan}
selectfor    

    4.3.5 非缓冲的channel

package mainimport (    "time"    "fmt")func main() {    sendingInterval := time.Second    receptionInterval := time.Second * 2    intChan := make(chan int,0)    go func() {        var ts0,ts1 int64        for i := 1; i <= 5; i++ {            intChan <- i            ts1 = time.Now().Unix()            if ts0 == 0 {                fmt.Println("Sent:",i)            } else {                fmt.Printf("Sent: %d [interval: %d s]\n",i,ts1-ts0)            }            ts0 = time.Now().Unix()            time.Sleep(sendingInterval)        }        close(intChan)    }()    var ts0,ts1 int64    Loop:        for {            select {            case v,ok := <- intChan:                if !ok {                    break Loop                }                ts1 = time.Now().Unix()                if ts0 == 0 {                    fmt.Println("Received:",v)                } else {                    fmt.Printf("Received: %d [interval: %d s]\n",v,ts1 - ts0)                }            }            ts0 = time.Now().Unix()            time.Sleep(receptionInterval)        }        fmt.Println("End.")}
chan0cap

    4.3.6 time包与channel

package mainimport (    "time"    "fmt")func main() {    timer := time.NewTimer(2 * time.Second)    fmt.Printf("Present time: %v.\n",time.Now())    expirationTime := <- timer.C    fmt.Printf("Expiration time: %v.\n",expirationTime)    fmt.Printf("Stop timer: %v.\n",timer.Stop())}
timerbase
package mainimport (    "fmt"    "time")func main() {    intChan := make(chan int,1)    go func() {        time.Sleep(time.Second)        intChan <- 1    }()    select {    case e := <- intChan:        fmt.Printf("Received: %v\n",e)    case <- time.NewTimer(time.Millisecond * 500).C:        fmt.Println("Timeout!")    }}
chantimeout1
package mainimport (    "time"    "fmt")func main() {    intChan := make(chan int,1)    go func() {        for i := 0; i < 5; i++ {            time.Sleep(time.Second)            intChan <- i        }        close(intChan)    }()    timeout := time.Millisecond * 500    var timer * time.Timer    for {        if timer == nil {            timer = time.NewTimer(timeout)        } else {            timer.Reset(timeout)        }        select {        case e,ok := <- intChan:            if !ok {                fmt.Println("End.")                return            }            fmt.Printf("Received: %v\n",e)        case <- timer.C:            fmt.Println("Timeout!")        }    }}
chantimeout2
package mainimport (    "time"    "fmt")func main() {    intChan := make(chan int,1)    ticker := time.NewTicker(time.Second)    go func() {        for _ = range ticker.C {            select {            case intChan <- 1:            case intChan <- 2:            case intChan <- 3:            }        }        fmt.Println("End. [sender]")    }()    var sum int    for e := range intChan {        fmt.Printf("Received: %v\n",e)        sum += e        if sum > 10 {            fmt.Printf("Got: %v\n",sum)            break        }    }    fmt.Println("End. [receiver]")}
tickercase

  4.4 实战演练:载荷发生器

    4.4.1 参数和结果

    4.4.2 基本构造

    4.4.3 初始化

    4.4.4 启动和停止

    4.4.5 调用器和功能测试

  4.5 小结

第5章 同步

  5.1 锁的使用

    5.1.1 互斥锁

package mainimport (    "sync"    "fmt"    "time")func main() {    var mutex sync.Mutex    fmt.Println("Lock the lock. (main)")    mutex.Lock()    fmt.Println("The lock is locked. (main)")    for i := 1; i <= 3; i++ {        go func(i int) {            fmt.Printf("Lock the lock. (g%d)\n",i)            mutex.Lock()            fmt.Printf("The lock is locked. (g%d)\n",i)        }(i)    }    time.Sleep(time.Second)    fmt.Println("Unlock the lock. (main)")    mutex.Unlock()    fmt.Println("The lock is unlocked. (main)")    time.Sleep(time.Second)}
repeatedlylock
package mainimport (    "sync"    "fmt")func main() {    defer func() {        fmt.Println("Try to recover the panic.")        if p := recover(); p != nil {            fmt.Printf("Recovered the panic(%#v).\n",p)        }    }()    var mutex sync.Mutex    fmt.Println("Lock the lock.")    mutex.Lock()    fmt.Println("The lock is locked.")    fmt.Println("Unlock the lock.")    mutex.Unlock()    fmt.Println("The lock is unlocked.")    fmt.Println("Unlock the lock again.")    mutex.Unlock()}
repeatedlyunlock

    5.1.2 读写锁

    5.1.3 锁的完整示例

  5.2 条件变量

  5.3 原子操作

    5.3.1 增或减

    5.3.2 比较并交换

    5.3.3 载入

    5.3.4 存储

    5.3.5 交换

    5.3.6 原子值

package mainimport (    "sync/atomic"    "fmt")func main() {    var countVal atomic.Value    countVal.Store([]int{
1,3,5,7}) anotherStore(countVal) fmt.Printf("The count value: %+v \n",countVal.Load())}func anotherStore(countVal atomic.Value) { countVal.Store([]int{
2,4,6,8})}
copiedvalue

    5.3.7 应用于实际

  5.4 只会执行一次

  5.5 WaitGroup

  5.6 临时对象池

  5.7 实战演练-Concurrent Map

  5.8 小结

第6章 网络爬虫框架设计和实现

  6.1 网络爬虫与框架

  6.2 功能需求和分析

  6.3 总体设计

  6.4 详细设计

    6.4.1 基本数据结构

    6.4.2 接口的设计

  6.5 工具的实现

    6.5.1 缓冲器

    6.5.2 缓冲池

    6.5.3 多重读取器

  6.6 组件的实现

    6.6.1 内部基础接口

    6.6.2 组件注册器

    6.6.3 下载器

    6.6.4 分析器

    6.6.5 条目处理管道

  6.7 调度器的实现

    6.7.1 基本结构

    6.7.2 初始化

    6.7.3 启动

    6.7.4 停止

    6.7.5 其他方法

    6.7.6 总结

  6.8 一个简单的图片爬虫

    6.8.1 概述

    6.8.2 命令参数

    6.8.3 初始化调度器

    6.8.4 监控调度器

    6.8.5 启动调度器

  6.9 扩展和思路

  6.10 本章小结

转载于:https://www.cnblogs.com/revoid/p/9358069.html

你可能感兴趣的文章
php 框架ci去index.php的方法
查看>>
Hyper-v学习(四),SMB虚拟机实时迁移
查看>>
基于spring3注解的google分页
查看>>
实用命令行工具详解—crontab
查看>>
code review
查看>>
我的心灵旅程:2019重新开始
查看>>
设置vim根据文件类型选择相应的编译器
查看>>
redis+ssh-keygen免认证登录案例
查看>>
HTML_后台框架全屏界面_fixed形式布局
查看>>
为什么使用 SLF4J 而不是 Log4J 来做 Java 日志
查看>>
顺丰快递接口
查看>>
淘宝技术发展(个人网站)
查看>>
处理 emoji 表情
查看>>
Dev-No.02 HTTP Status状态汇总
查看>>
linux svn命令
查看>>
Android中获取CPU负载和进程cpu时间
查看>>
docker容器启动后添加端口映射
查看>>
Android新姿势:3D翻转效果原理
查看>>
Xtrabackup系列之:二进制安装
查看>>
Context []startup failed due to previous errors 错误
查看>>