go语言关于线程与通道channal

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

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

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

比如:

package main

import(

         "fmt"

)
func main(){

    go fmt.Println("1")

    fmt.Println("2")    

}

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

你问我为啥?

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

那么怎么才能看到哪?

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

package main

import(

         "fmt"

)
func main(){

    go fmt.Println("1")

    fmt.Println("2")
   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<-1
    go func (){
        <-ch
        fmt.Println("1")
    }()
    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 mainimport(

"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

时间: 2024-11-03 03:57:08

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

【转】linux下C语言使用线程池(附带编码)

原文链接: linux下C语言使用线程池(附带编码) - china_sky - 博客频道 - CSDN.NEThttp://blog.csdn.net/feige2008/article/details/7827390 使用一个东西,我们要明白为什么使用它,如何使用它,使用它能达到什么效果 在写本文章时,我也借鉴了网上的部分资源,因为是之前很早搜索到的资料无法追踪源头,所以在此不再写来源,谨感谢各位大神. 1    使用线程池的原因 通常使用多线程都是在需要的时候创建一个新的线程,然后执行任务

c++11 语言级线程

c++11 语言级线程 线程的创建 用std::thread创建线程非常简单,只需要提供线程函数或函数对象即可,并且可以同时指定线程函数的参数. #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <chrono> #include <thread> void func1() { while (true) { std::this_thread::slee

并发——轻量级线程,通道,单向通道

1.轻量级线程 goroutine 是 Go语言中的轻量级线程实现,由 Go 运行时(runtime)管理.Go 程序会智能地将 goroutine 中的任务合理地分配给每个 CPU.Go 程序从 main 包的 main() 函数开始,在程序启动时,Go 程序就会为 main() 函数创建一个默认的 goroutine. 1)使用普通函数创建goroutine Go 程序中使用 go 关键字为一个函数创建一个 goroutine.一个函数可以被创建多个 goroutine,一个 gorouti

一起talk C栗子吧(第一百一十九回:C语言实例--线程死锁三)

各位看官们.大家好,上一回中咱们说的是线程死锁的样例,这一回咱们继续说该样例.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,由于篇幅的原因我们在上一回仅仅介绍了死锁发生的第一种原因,今天我们将介绍死锁发生的另外一种原因,而且该原因中的伪代码转换为实际的C语言代码. 为了方便,我们使用前面章回中演示相互排斥量的代码,在该代码的基础上做一些小改动来演示死锁.代码例如以下: 首先定义两个相互排斥量,相互排斥量是全局变量.方便线程使用. #if MUTEX_ENABLE pthread_m

c语言基础----线程

在头文件 threads.h 中,定义和声明了支持多线程的宏.类型和函数.所有直接与线程相关的标识符,均以前缀 thrd_ 作为开头.例如,thrd_t 是一个对象类型,它标识了一个线程. 创建并开始执行一个新线程thrd_create(): int thrd_create(thrd_t *thr, thrd_start_t func, void *arg); 参数 func 是一个指针,它指向在新线程需要被执行的函数,而 void 指针 arg 用于向该函数传递参数.换句话说,新线程将执行函数

一起talk C栗子吧(第一百二十一回:C语言实例--线程知识体系图)

各位看官们,大家好,上一回中咱们说的线程属性的例子,这一回咱们说的例子是:线程知识体系图.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在前面的章回中介绍了与线程相关的知识,在今天的章回中,我们将对这些知识进行总结,并且整理成一张知识体系图,方便大家掌握线程相关的知识. 下面是我们整理的知识体系图,请大家参数: 上图内容中的知识点都有相应的章回对应,下面是我整理的章回对应关系.为了大家方便,我设置了链接,大家可以直接点击链接跳到相应的章回中. 线程概念 线程概念:第一百零七回 线程标识

一起talk C栗子吧(第一百一十六回:C语言实例--线程同步之互斥量二)

各位看官们,大家好,上一回中咱们说的是线程同步之信号量的例子,这一回咱们继续说该例子.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在上一回中详细介绍了互斥量相关函数的用法,这一回中,我们介绍如何使用这些函数来操作互斥量. 下面是详细的操作步骤: 1.定义一个互斥量A,用来同步线程: 2.在创建线程的进程中使用pthread_mutex_init函数初始化互斥量,互斥量的属性使用默认值: 3.在读取数据的线程中读取数据,首先使用pthread_mutex_lock函数对互斥量A进行加锁

一起talk C栗子吧(第一百一十二回:C语言实例--线程同步概述)

各位看官们,大家好.上一回中咱们说的是线程间通信的样例,这一回咱们说的样例是:线程同步.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,提到同步.我想大家都不陌生,由于我们在前面章回中介绍过进程同步的内容. 大家都知道线程是轻量级的进程,尽管线程不像进程一样须要专门的通信机制,可是线程须要专门的同步机制. 今天我们来介绍一下线程同步的内容. 同步的含义对于进程和线程是同样的.仅仅是进程和线程实现同步的方式不同样.关于同步的含义,我们就不做具体的介绍了,假设大家忘记了,能够点击这里查看

python自动化--语言基础线程、生产者消费者示例

进程与线程的区别:进程不共享空间,线程共享地址空间 线程共享空间优缺点:优点:多线程给用户的体验好些,处理速度快些缺点:共享地址空间相互影响 1 import threading 2 import time 3 4 class Mythreading(threading.Thread): 5 def __init__(self,threadID,name,counter): 6 threading.Thread.__init__(self) #固定格式 7 self.threadID = thr