go并发编程以及socket通信的理解

go并发编程以及socket通信的理解

文章目录

一、管道的简单使用

" golang不是通过共享内存来通信,而是通过通信来共享内存 "

1、go简单初始化

go 复制代码
// golang不是通过共享内存来通信,而是通过通信来共享内存
func a1() {
	// 声明初始化 channel
	var ch chan string = make(chan string) // deadlock 会造成死锁,因为我们的管道是没有缓冲的
	// 内置的make函数有什么作用?
	// make 初始化内存,并且返回引用类型本身
	// new 只是将内存清零,返回的是指向类型的指针
	ch <- "hello" //阻塞写
	str := <-ch   //阻塞读
	fmt.Println(str)
	// 单向channel
	var ch1 chan<- string // 只能写
	var ch2 <-chan string // 只能读
	// 关闭channel
	close(ch1)
	x, ok := <-ch2
	if ok {
		fmt.Println(x)
	} else {
		fmt.Println("channel is closed")
	}
}

2、用 select 做一个简单的超时管理

go 复制代码
	// Go语言直接引入select关键字,用于处理异步问题
	var ch1, ch2 chan string
	select {
	case x := <-ch1: // 如果从ch1读取数据,那么执行此语句
		fmt.Println(x)
	case y := <-ch2: // 如果从ch2读取数据,那么执行此语句
		fmt.Println(y)
	default:
		fmt.Println("default")
	}

超时管理:

go 复制代码
func download(ch chan string) {
	for i := 1; i < 10; i++ {
		fmt.Println(i)
		time.Sleep(time.Second * 1)
	}
	ch <- "ok"
}
func a2() {
	// 超时处理
	timeout := make(chan int, 1)
	go func() {
		time.Sleep(time.Second * 3)
		timeout <- 1 // 用来标记超时,可以是任何非0值
	}()
	ch := make(chan string, 6) // 用于从download中接受数据
	go download(ch)
	select {
	case <-ch:
		fmt.Println("从ch中读取数据,执行正常业务处理") // 如果从ch中读取到数据那么正常处理业务
	case <-timeout:
		fmt.Println("3秒内没有从ch中读取数据,执行超时处理")// 如果从timeout中读取到数据,那么download执行超时
	}
}

3、编程体:通过go协程输出100个以内的任意两个数之和,减少等待。

go 复制代码
func add(i, x, y int) {
	fmt.Printf("%d + %d = %d\n", x, y, x+y)
}
func a3() {
	for i := 1; i <= 100; i++ {
		x := rand.Intn(100)
		time.Sleep(time.Millisecond)
		y := rand.Intn(100)
		go add(i, x, y)
	}
}

二、go中的socket实现通信

知识速记

go 复制代码
// 共享数据机制-sync
func s1() {
	// sync.Mutex
	//mutex := sync.Mutex{}

}

// 上下文机制 - Context

// socket 原理
/*
	互联网TCP/IP四层模型
	四层:数据层(帧)、网络层(IP)、传输层(TCP/UDP)、应用层(HTTP)
	通信:封包和解包
	抽象:应用程序到应用程序、进程到进程、主机到主机、设备到设备

*/

1、代码示例clinet.go和server.go

clinet.go

go 复制代码
package main
import (
	"bufio"
	"fmt"
	"net"
	"time"
)
func main() {
	// 与服务端建立连接
	conn, err := net.DialTimeout("tcp", "127.0.0.1:8899", time.Second)
	if err != nil {
		fmt.Printf("dial failed, err:%v\n", err)
		return
	}
	defer conn.Close()
	// 要发送的数据
	msg := []string{"hello world!", "golang", "c++", "python"}
	//  通过bufio方式发送
	writer := bufio.NewWriter(conn)
	for i, v := range msg {
		n, err := writer.Write([]byte(v))
		writer.Flush()
		if err != nil {
			fmt.Printf("write failed, err:%v\n", err)
			return
		}
		fmt.Printf("%d: write %d,bytes, data:%s\n", i, n, v)
		time.Sleep(time.Second)
	}
}

server.go

go 复制代码
// go 基于 socket 的 tcp 编程
func HandleConn(conn net.Conn) {
	fmt.Println("accepted a new connection!")
	defer conn.Close()
	for {
		// 负责缓存接受的数据
		buf := make([]byte, 32)
		n, err := conn.Read(buf) //表面上是 阻塞读
		if err != nil {
			fmt.Println("read err:", err)
			break
		}
		if n == 0 {
			continue
		}
		// 打印客户端发送的数据
		fmt.Printf("recv client data: %s\n", string(buf[:n]))
		// 发送数据给客户端
		conn.Write([]byte("hello client"))
	}
}
func main() {
	// 开始监听 8899 端口
	listen, err := net.Listen("tcp", ":8899")
	if err != nil {
		fmt.Println("listen err:", err)
		return
	}
	// 循环接受连接
	for {
		conn, err := listen.Accept()
		if err != nil {
			fmt.Println("accept err:", err)
			break
		}
		// 处理连接
		go HandleConn(conn)
	}
}

2、go基于 socket 的 tcp 编程

1、连接建立问题

连接拒绝:网络ping不通、ip或port指定错误、server未启动

listen backlog:增大server端listen backlog队列

网络延迟较大

2、读数据问题

无数据可读:goroutine阻塞即可

数据不足

超时

3、写数据问题

写阻塞

写入部分数据

4、线程安全问题

相关推荐
吴声子夜歌1 小时前
ApacheCommons——commons-pool2(高性能通用对象池框架)
java·开发语言·apache
mldong6 小时前
C# 开发者也有自己的轻量工作流引擎了:NuGet 装包,5 分钟跑通一条审批流
后端·c#·.net
kruptos7 小时前
分布式系统怎么“选主“?Raft 共识一次讲清
开发语言·分布式·php·共识算法
吴声子夜歌7 小时前
ApacheCommons——commons-cli(命令行参数解析)
java·开发语言·apache
爱学堂IT分享8 小时前
鹤翔老师pmp项目管理培训认证考试课 (直播录播题库送学时证明)【共58课时】-51CTO学堂
后端
benchmark_cc8 小时前
REST API 和 Python SDK 应该怎么选?量化交易数据接口选型实战
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
王的宝库8 小时前
Go 项目结构:从单文件到标准工程布局
开发语言·后端·golang
Tairitsu_H8 小时前
[C++] 深入理解红黑树:封装set与map
开发语言·c++·set·map·红黑树·模拟实现
泡海椒8 小时前
JQuick-Curl 性能分析:并发场景下的性能表现与调优,第三方接口调用不只要快写也要稳跑
java·开发语言·okhttp
小智老师PMP8 小时前
2026深度解析|PMP第八版与NPDP核心侧重点本质区别(管理类证书怎么选)
开发语言·分布式·算法·职场和发展·产品经理