进程和线程

A。进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。

B。线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

C。一个进程可以创建和撤销多个线程;同一进程中的多个线程之间可以并发执行。

并发和并行
并发:多线程程序在一个核的cpu上运行
并行:多线程程序在多个核的cpu上运行
举例。。一个妈给一个碗给多个小孩喂饭,,是并发
    一个妈给每个小孩一人一个碗,就是并行

并发                       并行

协程和线程
协程:独立的栈空间,共享堆空间,调度由用户自己控制,本质上有点类似于用户级协程,这些用户级线程的调度也是自己实现的。
线程:一个线程上可以跑多个协程,协程是轻量级的线程。

例子

package main

import (
"fmt"
"time"
) func test() {
var i int
for {
fmt.Println(i)
time.Sleep(time.Second)
i++
}
}
func main() {
go test() //起一个协程执行test()
for {
fmt.Println("i : runnging in main")
time.Sleep(time.Second )
}
}

-

--

设置Golang运行的cpu核数。

1.8版本以上,默认跑多个核

package main

import (
"fmt"
"runtime"
) func main() {
num := runtime.NumCPU()
runtime.GOMAXPROCS(num)
fmt.Println(num)
}

并发计算

package main

import (
"fmt"
"sync"
"time"
) var (
m = make(map[int]uint64)
lock sync.Mutex
) type task struct {
n int
} func calc(t *task) {
var sum uint64
sum =
for i := ; i < t.n; i++ {
sum *= uint64(i)
}
fmt.Println(t.n, sum)
lock.Lock()
m[t.n] = sum
lock.Unlock() } func main() {
for i := ; i < ; i++ {
t := &task{n: i}
go calc(t)//并发执行,谁快谁先出
}
time.Sleep( * time.Second)
//lock.Lock()
//for k, v := range m {
// fmt.Printf("%d!=%v\n", k, v)
//}
//lock.Unlock()
}

并发计算

Channel

channel概念
a。类似unix中的管道(pipe)
b.先进先出
c。线程安全,多个goroutine同时访问,不需要枷锁
d。channel是有类型的,一个整数的channel只能存整数

channel声明

var name chan string
var age chan int
var mapchan chan map[string]string
var test chan student
var test1 chan *student

channel初始化

使用make进行初始化
var test chan int
test = make(chan int,) var test chan string
test=make(chan string,)

channel基本操作

从channel读取数据
var testChan chan int
testChan = make(chan int, )
var a int
a = <-testChan

-从channel写入数据

var testChan chan int
testChan = make(chan int, )
var a int =
testChan <- a

第一个例子

package main

import "fmt"

type student struct {
name string
} func main() {
var stuChan chan *student
stuChan = make(chan *student, ) stu := student{name: "stu001"} stuChan <- &stu var stu01 interface{}
stu01 = <-stuChan var stu02 *student
stu02, ok := stu01.(*student)
if !ok {
fmt.Println("can not convert")
return
}
fmt.Println(stu02)
}

goroutine与channel

package main

import (
"fmt"
"time"
) //起一个读的协程
func write(ch chan int) {
for i := ; i < ; i++ {
ch <- i
}
} func read(ch chan int) {
for {
var b int
b = <-ch
fmt.Println(b)
}
} func main() {
intChan := make(chan int, )
go write(intChan)
go read(intChan)
time.Sleep( * time.Second)
}

读,取,字符串

package main

import (
"fmt"
"time"
) func sendData(ch chan string) {
ch <- "Washington"
ch <- "Tripoli"
ch <- "London"
ch <- "Beijing"
ch <- "Tokio"
} func getData(ch chan string) {
var input string
for {
input = <-ch
fmt.Println(input)
}
} func main() {
ch := make(chan string)
go sendData(ch)
go getData(ch)
time.Sleep( * time.Second)
}

读取字符串

Channel缓冲区

只能放一个元素的testChan
var testChan chan int
testChan = make(chan int)
var a int
a = <-testChan

-

testChan是带缓冲区的chan,一次可以放10个元素
var testChan chan int
testChan = make(chan int, )
var a int =
testChan <- a

-

package main

import (
"fmt"
"sync"
"time"
) var (
m = make(map[int]uint64)
lock sync.Mutex
) type task struct {
n int
} func calc(t *task) {
var sum uint64
sum =
for i := ; i < t.n; i++ {
sum *= uint64(i)
}
fmt.Println(t.n, sum)
lock.Lock()
m[t.n] = sum
lock.Unlock()
} func main() {
for i := ; i < ; i++ {
t := &task{n: i}
go calc(t)
}
time.Sleep( * time.Second)
lock.Lock()
for k, v := range m {
fmt.Printf("%d!=%v\n", k, v) }
lock.Unlock()
}

goroutine_lock

package main

import (
"fmt"
) func calc(taskChan chan int, resChan chan int, exitChan chan bool) {
for v := range taskChan {
flag := true
for i := ; i < v; i++ {
if v%i == {
flag = false
break
}
}
if flag {
resChan <- v
}
}
fmt.Println("exit")
exitChan <- true
}
func main() {
intChan := make(chan int, )
resultChan := make(chan int, )
exitChan := make(chan bool, )
go func() {
for i := ; i < ; i++ {
intChan <- i
}
close(intChan)
}()
for i := ; i < ; i++ {
go calc(intChan, resultChan, exitChan)
} //等待所有计算的goroutine全部退出
go func() {
for i := ; i < ; i++ {
<-exitChan
fmt.Println("wait goroute", i, "exited")
}
close(resultChan)
}()
for v := range resultChan {
fmt.Println(v)
} }

goroutine_sync

package main

import "fmt"

func send(ch chan int, exitChan chan struct{}) {
for i := ; i < ; i++ {
ch <- i
}
close(ch)
var a struct{}
exitChan <- a
}
func recv(ch chan int, exitChan chan struct{}) {
for {
v, ok := <-ch
if !ok {
break
}
fmt.Println(v)
}
var a struct{}
exitChan <- a
}
func main() {
var ch chan int
ch = make(chan int, )
exitChan := make(chan struct{}, ) go send(ch, exitChan)
go recv(ch, exitChan)
var total =
for _ = range exitChan {
total++
if total == {
break
}
}
}

goroutine_sync2

检测管道是否关闭

package main

import "fmt"

func main() {
var ch chan int
ch = make(chan int, )
for i := ; i < ; i++ {
ch <- i
}
close(ch)
for {
var b int
b, ok := <-ch
//检测管道是否关闭
if ok == false {
fmt.Println("chan is close")
break
}
fmt.Println(b)
}
}

检测管道是否关闭

如何关闭chan

. 使用内置函数close进行关闭,chan关闭之后,for range遍历chan中
已经存在的元素后结束
. 使用内置函数close进行关闭,chan关闭之后,没有使用for range的写法
需要使用,v, ok := <- ch进行判断chan是否关闭

chan的只读和只写

只读的声明
Var 变量的名字 <-chan int
Var readChan <- chan int 只写的声明
Var 变量的名字 chan<- int
Var writeChan chan<- int
package main

import "fmt"

//只写chan
func send(ch chan<- int, exitChan chan struct{}) {
for i := ; i < ; i++ {
ch <- i
}
close(ch)
var a struct{}
exitChan <- a
} //只读chan
func recv(ch <-chan int, exitChan chan struct{}) {
for {
v, ok := <-ch
if !ok {
break
}
fmt.Println(v)
}
var a struct{}
exitChan <- a
} func main() {
var ch chan int
ch = make(chan int, ) //初始化chan
exitChan := make(chan struct{}, ) go send(ch, exitChan)
go recv(ch, exitChan) var total =
for _ = range exitChan {
total++
if total == {
break
}
} }

只读只写示例chan

不阻塞

package main

import "fmt"
import "time" func main() {
var ch chan int
ch = make(chan int, )
ch2 := make(chan int, )
go func() {
var i int
for {
ch <- i
time.Sleep(time.Second)
ch2 <- i * i
time.Sleep(time.Second)
i++
}
}()
for {
select {
case v := <-ch:
fmt.Println(v)
case v := <-ch2:
fmt.Println(v)
case <-time.After(time.Second):
fmt.Println("get data timeout")
time.Sleep(time.Second)
}
}
}

chan不阻塞

Golang之并发篇的更多相关文章

  1. golang的并发

    Golang的并发涉及二个概念: goroutine channel goroutine由关键字go创建. channel由关键字chan定义 channel的理解稍难点, 最简单地, 你把它当成Un ...

  2. golang的并发不等于并行

    先 看下面一道面试题: func main() { runtime.GOMAXPROCS(1) wg := sync.WaitGroup{} wg.Add(20) for i := 0; i < ...

  3. go---weichart个人对Golang中并发理解

    个人觉得goroutine是Go并行设计的核心,goroutine是协程,但比线程占用更少.golang对并发的处理采用了协程的技术.golang的goroutine就是协程的实现. 十几个gorou ...

  4. golang实现并发爬虫三(用队列调度器实现)

    欲看此文,必先可先看: golang实现并发爬虫一(单任务版本爬虫功能) gollang实现并发爬虫二(简单调度器) 上文中的用简单的调度器实现了并发爬虫. 并且,也提到了这种并发爬虫的实现可以提高爬 ...

  5. Java并发篇

    Java并发篇 作者:星晴(当地小有名气,小到只有自己知道的杰伦粉) 1. Java锁 1.1 乐观锁 1.2 悲观锁 1.3 自旋锁 1.4 Synchronized 同步锁 1.4.1 核心组件 ...

  6. 多线程JUC并发篇常见面试详解

    @ 目录 1.JUC 简介 2.线程和进程 3.并非与并行 4.线程的状态 5.wait/sleep的区别 6.Lock 锁(重点) 1.Lock锁 2.公平非公平: 3.ReentrantLock ...

  7. Golang学习-第二篇 搭建一个简单的Go Web服务器

    序言 由于本人一直从事Web服务器端的程序开发,所以在学习Golang也想从Web这里开始学起,如果对Golang还不太清楚怎么搭建环境的朋友们可以参考我的上一篇文章 Golang的简单介绍及Wind ...

  8. Golang学习-第一篇 Golang的简单介绍及Windows环境下安装、部署

    序言 这是本人博客园第一篇文章,写的不到位之处,希望各位看客们谅解. 本人一直从事.NET的开发工作,最近在学习Golang,所以想着之前学习的过程中都没怎么好好的将学习过程记录下来.深感惋惜! 现在 ...

  9. 说说Golang goroutine并发那些事儿

    摘要:今天我们一起盘点一下Golang并发那些事儿. Golang.Golang.Golang 真的够浪,今天我们一起盘点一下Golang并发那些事儿,准确来说是goroutine,关于多线程并发,咱 ...

随机推荐

  1. Web 跨域请求(OCRS) 前端解决方案

    1.同源策略如下: URL 说明 是否允许通信 http://www.a.com/a.jshttp://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.j ...

  2. CSS层叠样式

    为了让网页元素的样式更加丰富,也为了让网页的内容和样式能拆分开,CSS由此思想而诞生,CSS是 Cascading Style Sheets 的首字母缩写,意思是层叠样式表.有了CSS,html中大部 ...

  3. centos7.3安装zip,unzip

    安装命令: yum install -y unzip zip

  4. Java的Synchronized

    原理,注意看输入输出,不了解原理是想不到会这样输出的. http://www.cnblogs.com/paddix/p/5367116.html 还有一个要注意的是一个对象一个monitor类

  5. Redis 集合 set 操作, 有序集合

    01, 唯一性, 确定性, 无序性 ( 结合的三大特性 ) 02, 新建集合, 或者往集合中添加数据 => sadd key value1 value2 value3 ....... 03, 查 ...

  6. 去除android手机浏览器中, 按住链接出现border的情况

    body{ -moz-user-select:none; -webkit-user-select:none; -webkit-tap-highlight-color:transparent; }

  7. 机器学习入门-DBSCAN聚类算法

    DBSCAN 聚类算法又称为密度聚类,是一种不断发张下线而不断扩张的算法,主要的参数是半径r和k值 DBSCAN的几个概念: 核心对象:某个点的密度达到算法设定的阈值则其为核心点,核心点的意思就是一个 ...

  8. greenlet 实现手动协程切换

    from greenlet import greenlet def test1(): print('12') gr2.switch() #切换到gr2 print('34') gr2.switch() ...

  9. nginx 限制ip

    转自:https://www.cmsky.com/nginx-deny-ip/ 面对垃圾留言和暴力破解,我们可以封禁IP,前文介绍过Apache环境使用.htacess来屏蔽IP,Nginx也可以做到 ...

  10. 7 python 模块间相互导入

    python在不同层级目录import模块的方法 注意,在python3里,即使目录下没__int__.py文件也能创建成功,猜应该是解释器优化所致,但创建包还是要记得加上这个文件 吧. 1.模块的分 ...