九、goroutine和channel

进程和线程

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

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

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

  nginx是       进程    ----》Fork多个子进程   --》多线程   --》多进程程序

 

协程和线程

 

协程:独立的栈空间,共享堆内存,调度由用户自己控制,本质上有点类似于用户级线程,这些用户线程的调度也是自己实现的

线程:一个线程上可以跑多个协程,协程是轻量级的线程

线程分为用户态的线程和操作系统级别的线程

 

goroutine

 

package main

import (
   "fmt"
   "time"
)

func test(){
   var i int
   for {
      fmt.Println(i)
      time.Sleep(time.Second)
      i++
   }
}

func main(){
   go test()
   for{
      fmt.Println("i running in main")
      time.Sleep(time.Second) //必须要加上,防止main线程跑的太快看不清
   }
}

执行结果
D:\project>go build go_dev/day8/example
D:\project>example
i running in main
0
1
i running in main
i running in main
2
3
i running in main
i running in main
4
5
i running in main
i running in main
6

 

goroutine调度模型

 

M:系统里面的线程

P:调度器

G:协程 goroutine

 

1)可以看出上面的每个操作系统线程有4个协程执行,只不过有3个协程是在队列中执行

2)可以看出一个线程可以多个协程在跑

 

在1.8之前可以把程序设置到init函数里面,1.8以上不用设置cpu的核心数

 

如何设置golang运行的cpu核数

 

package main

import (
   "runtime"
   "fmt"
)

func main(){
   num := runtime.NumCPU()      //查找当前cpu的核心数量
   runtime.GOMAXPROCS(num)  //设置golang运行核数 这里结果为8
   fmt.Println(num)
}
运行结果
8
View Code

channel声明

var 变量名 chan 类型

var test chan int

var test chan string

var test chan map[string] string

var test chan stu

var test chan *stu

channl初始化使用make

变量名 = make (chan 类型 size)

创建map类型往channel里面添加数据

 

创建map类型往channel里面添加数据
package main

func main(){
   var mapchan chan map[string]string       //声明channel
   mapchan = make(chan map[string]string ,10)  //初始化channel
   m := make(map[string]string)          //初始化map
   m["stu01"]="stu01"

   mapchan <- m                      //往channel里面添加数据
}

创建struct,往channel里面添加数据
package main

type student struct{
   name string
}

func main(){
   var stuchan chan student
   stuchan = make(chan student,10)
   
   stu:=student{name:"stu01"}
   
   stuchan <- stu
   
}

指针形式添加到channel
package main

type student struct{
   name string
}

func main(){
   var stuchan chan *student
   stuchan = make(chan *student,10)

   stu:=student{name:"stu01"}

   stuchan <- &stu

}

channel超时处理

利用select来处理chan超时

 

for {
    select {
    case v := <-chan1:
        fmt.Println(v)
    case v := <-chan2:
        fmt.Println(v)
    default:
        time.Sleep(time.Second)
        fmt.Println("timeout...")
    }
}
View Code

 

time.After()定时器来做处理。

在time.After()计时器触发之前,底层计时器不会被垃圾收集器回收。

转载于:https://www.cnblogs.com/pyrene/p/8094357.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值