并发,线程,协程:概念是不可能概念的,google去吧。或者点击这里,查看上一篇文章golang
名称 | 特色 |
---|---|
管道/匿名管道(pipe) | 管道的实质是一个内核缓冲区 |
有名管道(FIFO) | 先进先出(first in first out); 以有名管道的文件形式存在于文件系统中; |
信号(Signal) | 无需知道该进程的状态; 阻塞进程; 异步通讯; |
消息队列(Message Queue) | 放在内核中的消息链表; 容许一个或多个进程向它写入与读取消息; 克服了信号承载信息量少缺陷; 目前主要有两种类型的消息队列:POSIX消息队列以及System V消息队列,系统V消息队列目前被大量使用; |
共享内存(share memory) | 使得多个进程能够能够直接读写同一块内存空间,是最快的可用IPC形式; 因为多个进程共享一段内存,所以须要依靠某种同步机制(如信号量)来达到进程间的同步及互斥; |
信号量(semaphore) | 信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步只能经过两个标准原子操做:wait(semap) , signal(semap) ;进行访问 信号量是非负整型变量 操做也被成为PV原语(P来源于荷兰语proberen"测试",V来源于荷兰语verhogen"增长",P表示经过的意思,V表示释放的意思) |
套接字(socket) | 套接字是支持TCP/IP的网络通讯的基本操做单元 套接字的特性由3个属性肯定,它们分别是:域、端口号、协议类型。 |
信号量与互斥量之间的区别:
(1)互斥量用于线程的互斥,信号量用于线程的同步。这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。
互斥:是指某一资源同时只容许一个访问者对其进行访问,具备惟一性和排它性。但互斥没法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数状况),经过其它机制实现访问者对资源的有序访问。
在大多数状况下,同步已经实现了互斥,特别是全部写入资源的状况一定是互斥的。少数状况是指能够容许多个访问者同时访问资源
(2)互斥量值只能为0/1,信号量值能够为非负整数。
也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量能够实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也能够完成一个资源的互斥访问。
(3)互斥量的加锁和解锁必须由同一线程分别对应使用,信号量能够由一个线程释放,另外一个线程获得。缓存
基本上就是推荐使用channel,这个是最推荐的使用形式;网络
还有就是使用sync.Mutex
互斥锁进行加锁通信;多线程
更详细的介绍之后写;并发
这种状况下,通常是不一样『数据集合』须要进行『处理』,在处理的过程当中两个数据集合对『结果』形成的影响没有时序行;异步
这种状况下,彻底能够采用两个数据单独进行协程处理而后再进行后续运算;socket
// 伪代码 var result, data1, data2 int32 done1 := make(chan bool) done2 := make(chan bool) // 第一个数据集合,须要求和 go func() { for _, val := range dataset1 { data1 += val } done1 <- true } // 第二个数据集合,须要求和 go func() { for _, val := range dataset2 { data2 += val } done2 <- true } // 等待协程完成运算 <-done1 <-done2 // 结果进行相加 result = data1 + data2
通常有些业务处理之后,有些『额外工做』须要处理可是不耽误主协程返回数据,这个时候就能够开个协程去作,不用等待post
// 伪代码 result, err := processMethod() if err != nil { ..... } // 须要对结果进行写缓存等其余操做,不耽误数据返回 go func() { err = saveRedis(result) if err != nil { ..... } } return result
例如,经过管道channel发送某些数据,若超时则自动放弃本次发送,关闭通道。测试
// 定义两个有缓冲通道,容量分别为1 c1 := make(chan string, 1) c2 := make(chan string, 1) go func() { time.Sleep(time.Second * 1) // 隔1秒发送数据 c1 <- "data1" }() go func() { time.Sleep(time.Second * 6) // 隔6秒发送数据 c2 <- "data2" }() for i := 0; i < 2; i++ { // 给通道建立容忍时间,若是5s内没法读写,就即刻返回 tm := time.NewTimer(time.Second * 5) // 使用select来获取这两个通道的值,而后输出 select { case data1 := <-c1: // 接收c1通道数据(消费数据) fmt.Println(msg1) case data2 := <-c2: // 接收c2通道数据(消费数据) fmt.Println(msg2) case <-tm.C: fmt.Println("timeout!") } }