通信改变内存 通过内存通信
1. 通过内存通信
1.1 这里要了解一下并发(假设大家都懂Java|C++)
1.1.1 在传统的编程语言中,并发的通信都是通过内存的改变而通信
-
举个例子
-
我现在有两个线程执行一个for循环,目的是在List中添加10个数据 主线程 添加3个
剩下7个由Thread1 和 main(主线程) 共同完成
-
参考下列代码:
- 当内存中list的数据长度到达3的时候,通知另一个线程 这个就是通过内存通信了
-
List<int> list = new ArrayList()<>;
//Thread1
Thread thread1 = new Thread(()->{
for (int i = 0;i<9;i++){
list.add(i)
if(list.length == 10){
break;
}
}
});
public static void main(String []args) {
addDataMain();
}
//Main
public static void addDataMain(){
for (int i = 0;i<9;i++){
list.add(i)
if(i == 2){
thread1.start();
}
if(list.length == 10){
break;
}
}
}
2. 通信改变内存
2.1 这里默认大家都懂golang
2.1.1 golang 中通信是通过管道(channel)完成的
- 管道说白了就是 一种数据结构(FIFO) 队列的形式
- 从channel中读取数据的goroutine 会先收到数据
- 向channel中发送数据的goroutine 会先得到发送数据的权利
- 向channel发送数据后会唤醒读取数据的goroutine
- 如果channel 缓冲区满了 发送数据的goroutine会休眠
- 读取数据的goroutine读不到会阻塞(如果没有发送数据那么会报错)
- 举个例子
- 以下代码就是通信改变内存
- 先在缓冲区写入50条数据 写入完成后关闭通道
- 然后读取数据 读取完之后给channel2 写入数据
<- channel2
这里只能在channel2 写入后才能读取 不然一直阻塞- 这里已经改变了channel1
package main
//数据
var channel1 chan int= make(chan int,50)
//用作通信的管道
var channel2 chan bool = make(chan bool,1)
//添加数据
func main(){
go func(){
for i<:0; i<50 ; i++{
channel1 <- i
}
close(channel1)
}()
go func(){
for {
num,ok := <- channel1
if(!ok){
break
}
}
channel2 <- true
}()
<- channel2
}