在go语言中,封装了多线程的使用方法,使其变得简单易用。

在这里说说自己一点体会,不正确的地方还是请各位大牛指正。

关于go语言的并发机制,这很简单,在你要执行的函数前面加上go即可

比如:

package main

import(

         "fmt"

)
func main(){ go fmt.Println("") fmt.Println("") }

好了 这样即可使用,但是这个程序运行的时候会出问题,你会发现1打印不出来,为啥?

你问我为啥?

这是因为在执行这个的时候,你可以想像,程序优先执行主线程,这时会打印出2,然后程序就退出了,这个时候程序还没来及打印并发下的1,就退出了所以你看不到!!

那么怎么才能看到哪?

加个延时,等到线程把事情搞完才退出就能看到了,就像这样

package main

import(

         "fmt"

)
func main(){ go fmt.Println("") fmt.Println("")

   time.Sleep(time.Second*1)
}

这样你就会发现,其实程序先打印2,在打印1,因为是主线程优先的,所以会出现这种状况(我猜的,管你信不信,好吧这是真的,你问谁都是这样给你说)

不管怎么说,我就问你这个多线程学起来简单不简单?你觉得是CreateThread()爽,还是这个爽!

下面说说通道channal

这个哪,你就可以理解成多线程之间通信的一个通道。

你问我怎么用这东西?

ch:=make (chan int)

chan是通道的关键字

make那就是创建的意思

int 那就是int类型的通道

简单不简单,开心不开心?

你开心的太早了,哈哈哈哈哈

上面仅仅是说了基本的用法,这里还有点东西需要在详细的说下,不然你还是不懂怎么用chan搞事情!

上面的

ch := make(chan int)

是创建一个无缓冲区的int类型的chan,具体什么叫无缓冲区,额,不知道怎么解释,以后再说吧

ch :=make(<-chan int)

这个是无缓冲区只读的ch

ch:=make(chan<- int)

无缓冲只写的 chan

关于"<-"符号,在go的多线程中会经常碰到,你需要知道一点这个是做什么用的

按照我的理解:

ch<-

这个意思是将数据写入ch

<-ch这个意思是将数据从ch中读出来

还是一个小例子说下相关的东西:

package main
import( "fmt" // "time"
)
func main(){ ch:=make(chan int)
ch<-
go func (){
<-ch
fmt.Println("")
}()
fmt.Println(":2") }

运行之后会告诉你,死锁了,为什么会出现?他是无缓冲区,也就是赋值必须要进去取值。不然就是死锁

package main
import( "fmt" // "time"
"time"
)
func main(){ ch:=make(chan int,1)
ch<-1 go func (){
v:=<-ch
fmt.Println(v)
}()
fmt.Println(":2")
time.Sleep(time.Second*1) }

这样试试看哪

package main
import( "fmt" // "time"
"time"
)
func main(){ ch:=make(chan int) go func (){
v:=<-ch
fmt.Println(v)
}()
ch<-1
fmt.Println(":2") }

或者这样,后面这个是无缓冲区的,这样的话,ch在赋值的时候被阻塞,知道gofunc给取走,这样打印出来的结果就是1,2

生产消费者:

import (

    "fmt"
    "time"
)
func produce(p chan<- int) {
    for i := 0; i < 10; i++ {
        p <- i
        fmt.Println("send:", i)
    }
}
func consumer(c <-chan int) {
    for i := 0; i < 10; i++ {
        v := <-c
        fmt.Println("receive:", v)
    }
}
func main() {
    ch := make(chan int)
    go produce(ch)
    go consumer(ch)
    time.Sleep(1 * time.Second)
}

这个例子,我觉得能够体现的更明显,无缓冲区意味着这就是同步的,也就是说只能是ch写入,取出,写入,取出,写入,取出这样走,无缓冲区必须保证一个写入,另一个取出,才能执行下一次

再看看这个:

import (

    "fmt"
    "time"
)
func produce(p chan<- int) {
    for i := 0; i < 10; i++ {
        p <- i
        fmt.Println("send:", i)
    }
}
func consumer(c <-chan int) {
    for i := 0; i < 10; i++ {
        v := <-c
        fmt.Println("receive:", v)
    }
}
func main() {
    ch := make(chan int, 10)
    go produce(ch)
    go consumer(ch)
    time.Sleep(1 * time.Second)
}

再来看看这个,这个有缓冲区的,啥意思?

就是我有个容器,我可以一直往里面生产,知道这个被填满,也就是我可以一直往这个缓冲区塞东西,直到这10个被填满,我也可以一直读数据,也可以一下全部取出来。

大概就是这么意思。

参考文档:

http://studygolang.com/articles/3311

go语言关于线程与通道channal的更多相关文章

  1. c++11 语言级线程

    c++11 语言级线程 线程的创建 用std::thread创建线程非常简单,只需要提供线程函数或函数对象即可,并且可以同时指定线程函数的参数. #define _CRT_SECURE_NO_WARN ...

  2. C语言实现线程池功能

    1. 线程池基本原理 2. 线程池C语言实现 2.1 线程池的数据结构 #include <stdio.h> #include <pthread.h> #include < ...

  3. Go语言规格说明书 之 通道类型(Channel types)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  4. go语言-csp模型-并发通道

    [前言]go语言的并发机制以及它所使用的CSP并发模型 一.CSP并发模型 CSP模型是上个世纪七十年代提出的,用于描述两个独立的并发实体通过共享的通讯 channel(管道)进行通信的并发模型. C ...

  5. JAVA语言规范-线程和锁章节之同步、等待和通知

    JAVA语言规范:线程和锁 1 同步 java编程语言提供了线程间通信的多种机制.这些方法中最基本的是同步化,此方法是使用监视器实现的.JAVA中每个对象与一个监视器相关联,一个线程可以加锁和解锁监视 ...

  6. go语言实现线程池

    话说真的好久没有写博客了,最近赶新项目,工作太忙了.这一周任务比较少,又可以随便敲敲了. 逛论坛的时候突发奇想,想用go语言实现一个线程池,主要功能是:添加total个任务到线程池中,线程池开启num ...

  7. golang 线程与通道

    首先我们来看线程,在golang里面也叫goroutine 在读这篇文章之前,我们需要了解一下并发与并行.golang的线程是一种并发机制,而不是并行.它们之间的区别大家可以上网搜一下,网上有很多的介 ...

  8. Go语言规格说明书 之 通道 发送语句(send) 和 接收操作符(receive)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  9. 理解线程3 c语言示例线程基本操作

    Table of Contents 1. 基本线程的动作 1.1. 设置线程属性 1.1.1. 设置脱离状态 1.1.2. 设置调度属性 1.2. 取消线程 1.3. 主线程创建多个线程示例 2. 了 ...

随机推荐

  1. Project Euler 75: Singular integer right triangles

    题目链接 思路: 勾股数组,又称毕达格拉斯三元组. 公式:a = s*t b = (s^2 - t^2) / 2 c = (s^2 + t^2) / 2 s > t >=1 且为互质的奇数 ...

  2. 【转】RTP学习笔记

    转自:https://www.cnblogs.com/yoyotl/p/5650101.html 一.定义 实时传输协议(Real- time Transport Protocol,RTP)是在Int ...

  3. vue单位文本控件与vue加密文本控件

    vue单位文本控件: 使用方式: npm install dami-text-input --save 使用: <text-input v-model="test" :uni ...

  4. C# 关键字new用法

    1.实例化对象,执行构造函数. public class Test { public Test(string name) { Console.WriteLine(name); } } public c ...

  5. hbase-0.92.1表备份还原

    原表结构和数据 hbase(main):021:0* describe 'test' DESCRIPTION ENABLED {NAME => ', TTL = true > ', COM ...

  6. Ubuntu LNMP系统搭建Zabbix监控

    系统环境 操作系统类型:Ubuntu 系统环境版本:4.4.0-122-generic IP地址:192.168.152.118 第一步:选择适当的操作系统类型与各项的版本要求,我这边直接使用LNMP ...

  7. vue-实例生命周期钩子(不太明白)

    每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue({ // 选项}) 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要 ...

  8. GNOME 系统设置

    详细的GNOME系统设置全文,参见这里. 以下摘录使用到的部分. 1. 在任务栏上显示日期或周几(二选一).秒数 $ gsettings set org.gnome.desktop.interface ...

  9. BZOJ2662 [BeiJing wc2012]冻结

    网上的题解都是分层图+spfa或者dijkstra 我觉得dijk太难写了,懒得写,看了一下数据范围$N=50$,这显然是出题人勾引人犯罪 我决定使用floyd的做法,令$f[i][j][t](k)$ ...

  10. 前端页面的适配使用rem换算

    前端页面的适配使用rem换算 https://www.cnblogs.com/liangxuru/p/6970629.html 注:本文转载之处:https://www.cnblogs.com/ann ...