Go并发编程实战 (郝林 著)
第1章 初识Go语言
1.1 语言特性
1.2 安装和设置
1.3 工程构造
1.3.1 工作区
1.3.2 GOPATH
1.3.3 源码文件
package main
import (
    "fmt"
    "runtime"
)
:::"C"}
var info string
func 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 main
import (
    "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)-]
        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 main
import "fmt"
var v = "1,2,3"
func main() {
    v := [],,}
    if v != nil {
        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 main
import (
    "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()
    } else {
        name := input[:len(input)-]
        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)-]
        input = strings.ToLower(input)
        switch input {
        case "":
            continue
        case "nothing","bye":
            fmt.Println("Bye!")
            os.Exit()
        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 main
func main() {
    go println("Go!Goroutine!")
}
gobase1
package main
import "time"
func main() {
    go println("Go! Goroutine!")
    time.Sleep(time.Millisecond)
}
gobase2
package main
import (
    "fmt"
    "time"
)
func main() {
    name := "Eric"
    go func() {
        fmt.Printf("Hello,%s!\n",name)
    }()
    name = "Harry"
    time.Sleep(time.Millisecond)
}
gobase3
package main
import (
    "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 main
import (
    "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 main
import (
    "fmt"
    "time"
)
)
func main() {
    syncChan1 := make(chan )
    syncChan2 := make(chan )
    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 * )
        close(strChan)
        syncChan2 <- struct{}{}
    }()
    <-syncChan2
    <-syncChan2
}
chanbase1
package main
import (
    "fmt"
    "time"
)
)
func main() {
    syncChan := make(chan )
    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)
        ; i < ; i++ {
            mapChan <- countMap
            time.Sleep(time.Millisecond)
            fmt.Printf("The count map: %v. [sender]\n",countMap)
        }
        close(mapChan)
        syncChan <- struct{}{}
    }()
    <-syncChan
    <-syncChan
}
chanval1
package main
import (
    "fmt"
    "time"
)
type Counter struct {
    count int
}
)
func main() {
    syncChan := make(chan )
    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{},
        }
        ; i < ; i++ {
            mapChan <- countMap
            time.Sleep(time.Millisecond)
            fmt.Printf("The count map: %v. [sender]\n",countMap)
        }
        close(mapChan)
        syncChan <- struct{}{}
    }()
    <- syncChan
    <- syncChan
}
chanval2
package main
import "fmt"
func main() {
    dataChan := make(chan )
    syncChan1 := make(chan )
    syncChan2 := make(chan )
    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() {
        ; i < ; 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 main
import (
    "fmt"
    "time"
)
)
func main() {
    syncChan1 := make(chan )
    syncChan2 := make(chan )
    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 * )
    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 main
import "fmt"
func main() {
    var ok bool
    ch := make(chan )
    _,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<- )
    _,ok = interface{}(sch).(chan int)
    fmt.Println("chan<- int => chan int:",ok)
    rch := make(<-chan )
    _,ok = interface{}(rch).(chan int)
    fmt.Println("<-chan int => chan int:",ok)
}
chanconv
4.3.3 for语句与channel
package main
import (
    "fmt"
    "time"
)
)
func main() {
    syncChan1 := make(chan )
    syncChan2 := make(chan )
    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 * )
    close(strChan)
    syncChan2 <- struct{}{}
}
chanbase3
4.3.4 select语句
package main
import "fmt"
var intChan1 chan int
var intChan2 chan int
var channels = []chan int{intChan1,intChan2}
,,,,}
func main() {
    select {
    ) <- getNumber():
        fmt.Println("1th case is selected.")
    ) <- getNumber():
        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 main
import "fmt"
func main() {
    chanCap :=
    intChan := make(chan int,chanCap)
    ; i < chanCap; i++ {
        select {
        :
        :
        :
        }
    }
    ; i < chanCap; i++ {
        fmt.Printf("%d\n",<-intChan)
    }
}
selectrandom
package main
import "fmt"
func main() {
    intChan := make(chan )
    ; i < ; i++ {
        intChan <-
    }
    close(intChan)
    syncChan := make(chan )
    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 main
import (
    "time"
    "fmt"
)
func main() {
    sendingInterval := time.Second
    receptionInterval := time.Second *
    intChan := make(chan )
    go func() {
        var ts0,ts1 int64
        ; i <= ; i++ {
            intChan <- i
            ts1 = time.Now().Unix()
             {
                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()
                 {
                    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 main
import (
    "time"
    "fmt"
)
func main() {
    timer := time.NewTimer( * 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 main
import (
    "fmt"
    "time"
)
func main() {
    intChan := make(chan )
    go func() {
        time.Sleep(time.Second)
        intChan <-
    }()
    select {
    case e := <- intChan:
        fmt.Printf("Received: %v\n",e)
    ).C:
        fmt.Println("Timeout!")
    }
}
chantimeout1
package main
import (
    "time"
    "fmt"
)
func main() {
    intChan := make(chan )
    go func() {
        ; i < ; i++ {
            time.Sleep(time.Second)
            intChan <- i
        }
        close(intChan)
    }()
    timeout := time.Millisecond *
    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 main
import (
    "time"
    "fmt"
)
func main() {
    intChan := make(chan )
    ticker := time.NewTicker(time.Second)
    go func() {
        for _ = range ticker.C {
            select {
            :
            :
            :
            }
        }
        fmt.Println("End. [sender]")
    }()
    var sum int
    for e := range intChan {
        fmt.Printf("Received: %v\n",e)
        sum += e
         {
            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 main
import (
    "sync"
    "fmt"
    "time"
)
func main() {
    var mutex sync.Mutex
    fmt.Println("Lock the lock. (main)")
    mutex.Lock()
    fmt.Println("The lock is locked. (main)")
    ; i <= ; 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 main
import (
    "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 main
import (
    "sync/atomic"
    "fmt"
)
func main() {
    var countVal atomic.Value
    countVal.Store([],,,})
    anotherStore(countVal)
    fmt.Printf("The count value: %+v \n",countVal.Load())
}
func anotherStore(countVal atomic.Value) {
    countVal.Store([],,,})
}
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 本章小结
Go并发编程实战 (郝林 著)的更多相关文章
- 《Go并发编程实战》第2版  紧跟Go的1.8版本号
		文章作者:郝林(<Go并发编程实战 (第2版)>作者) 最终来了! 经过出版社的各位编辑.校对.排版伙伴与我的N轮PK和共同努力,<Go并发编程实战>第2版的全部内容最终全然确 ... 
- Scala 深入浅出实战经典 第66讲:Scala并发编程实战初体验
		王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ... 
- 【Java并发编程实战】----- AQS(四):CLH同步队列
		在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ... 
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
		在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ... 
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
		上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ... 
- 【Java并发编程实战】-----“J.U.C”:Exchanger
		前面介绍了三个同步辅助类:CyclicBarrier.Barrier.Phaser,这篇博客介绍最后一个:Exchanger.JDK API是这样介绍的:可以在对中对元素进行配对和交换的线程的同步点. ... 
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
		上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ... 
- 【Java并发编程实战】-----“J.U.C”:CyclicBarrier
		在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ... 
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
		ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ... 
随机推荐
- java读取UTF-8的txt文件发现开头的一个字符问题
			今天遇到一个奇葩问题,在读取一个TXT文件时,出现开头多了一个问号(?).如下图: 莫名奇妙的多了一个.最后通过网上资料,知道在Java中,class文件采用utf8的编码方式,JVM运行时采用utf ... 
- RabbitMQ(3)  Spring boot集成RabbitMQ
			springboot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spring-boot-starter-amqp项目对消息各种支持. 资源代码:练习用的代码. ... 
- Python下探究随机数的产生原理和算法
			资源下载 #本文PDF版下载 Python下探究随机数的产生原理和算法(或者单击我博客园右上角的github小标,找到lab102的W7目录下即可) #本文代码下载 几种随机数算法集合(和下文出现过的 ... 
- python_入门_三级菜单
			'''程序:三级菜单要求:1.打印省.市.县三级菜单2.可返回上一级3.可随时退出程序''' # -*- coding: utf-8 -*- # __author__ = 'qi' prov_city ... 
- 如何分析java内存泄漏问题
			java中的内存泄漏首先需要dump文件出来,主要包括内存dump.线程dump: 内存dump是指通过jmap -dump <pid>输出的文件,而线程dump是指通过jstack &l ... 
- DBMS_NETWORK_ACL_ADMIN (OCP 053 第七题)
			You create an access control list(ACL)using the DBMS_NETWORK_ACL_ADMIN package It is a list of users ... 
- mybatis_generator合并xml和Java
			之前写了合并xml的插件,今天改了改mybatis-generator源码,合并java和xml都改进去了. 先上图吧. 左边是一开始生成的,中间去掉author加了password字段和方法,右边重 ... 
- javascript高级程序设计第3版——第一章概括
			最近发现Xmind思维导图是个好东西,刚好开始看书,被用来归纳最好不过了 
- 密码机制(PGP)
			01 PGP概念 02 PGP认证加密体系 
- Daily record-September
			September11. I feel much more reassured when I've been for a health check. 体检之后我感到放心多了.2. The diseas ... 
