golang并发编程与系统标准库

协程:Goroutine

package main

import (
	"fmt"
	"sync"
)

type safeInt struct {
	a    int
	lock sync.Mutex
}
//对a 加锁
func (si *safeInt) increase() {
	si.lock.Lock()
	defer si.lock.Unlock()
	si.a++
}

func (si *safeInt) get() int {
	si.lock.Lock()
	defer si.lock.Unlock()
	return si.a
}

func main() {
	var si safeInt
	si.increase()
    
    //WaitGroup共享内存方式实现并发
	var wg sync.WaitGroup
	for i := 0; i < 5000; i++ {
		wg.Add(1)
		go func() {
			si.increase()
			defer wg.Done()
		}()
		wg.Wait()
	}

	fmt.Println(si.get())

}

  • 在执行函数前面加上go关键字就表示一个执行一个协程
  • 协程是更轻量级的线程,属于非抢占式的线程调度,底层实际还是线程
  • main函数也是一个协程
  • io操作会交出协程控制权或使用权

channel(常用)

//创建chan的方法
var c chan int // c = nil
c := make(chan int)
  • channel是协程与协程之间的一个通道
  • 通过make关键字创建channel
  • ch <- x 从通道接收数据,x <- ch 从通道中读取数据
  • channel可以使用close()函数来关闭
  • range channel可以直接取到channel的值
  • 通道在前发送数据,通道在后接受数据
  • 如果没有 goroutine 读取 channel,则发送者会一直阻塞

buffered channel 和select

package main

import (
	"fmt"
	"time"
)

func bufferedChannelDemo() {
	c := make(chan int, 3)

	go func() {
		for {
			n := <-c
			fmt.Println(n)
		}
	}()
	c <- 10
	c <- 20
	c <- 30
	c <- 40
}

func selectDemo() {
	ch1 := make(chan int)
	ch2 := make(chan int)

	timeout := make(chan bool)
	go func() {
		time.Sleep(time.Second)
		timeout <- true
	}()
	go func() {
		ch1 <- 10
	}()

	//使用select语句和default case来实现非阻塞
	for {
		select {
		case <-ch1:
			fmt.Println("receive data from ch1")
		case <-ch2:
			fmt.Println("receive data from ch2")
		case <-timeout:
			fmt.Println("timeout")
			return
		default:
			fmt.Println("no data to send channel")
		}
	}

}

//检测channel是否已满
func checkChannelFull(c chan int) {
	select {
	case c <- 2:
	default:
		fmt.Println("channel is full")
	}
}

func main() {
	//selectDemo()
	//bufferedChannelDemo()
	//time.Sleep(time.Millisecond)
	//<-time.After(time.Millisecond)
	c := make(chan int, 3)
	c <- 1
	c <- 2
	checkChannelFull(c)
}

  • 带缓冲的通道,可以用make设置缓冲大小
  • 在缓冲被全部使用之前,给一个带缓冲的通道发送数据是不会被阻塞的,而从通道读取数据也不会被阻塞,知道缓冲空了为止
  • default case可以确保发送不会被阻塞
  • 如果阻塞了,会等待直到其中一个可以处理,如果多个可以处理,则随机选择一个处理

http标准库

1、发起request请求:

//自定义http请求添加请求头
func sendRequest() {
	req, err := http.NewRequest(http.MethodGet, "http://www.baidu.com", nil)
	if err != nil {
		panic(err)
	}
	//添加请求头
	req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36")

	//发起request请求
	resp, err := http.DefaultClient.Do(req)

	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	//获取请求body
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(body))
}



//不添加请求头方式请求
func sendRequest() {
	req, err := http.Get("http://www.youdianzhishi.com")
	if err != nil {
		panic(err)
	}
	defer req.Body.Close()

	data, err := ioutil.ReadAll(req.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(data))

}

2、使用http库构建server

//获取文本
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		io.WriteString(writer, "Hello World")
	})


//获取json
http.HandleFunc("/json", func(writer http.ResponseWriter, request *http.Request) {

		user := User{
			Name: "James",
			Age:  20,
		}

		userJson, err := json.Marshal(user)
		if err != nil {
			http.Error(writer, err.Error(), http.StatusInternalServerError)
			return
		}
		writer.Header().Set("Content-Type", "Application/json")
		writer.Write(userJson)
	})

log.Fatalln(http.ListenAndServe("localhost:8080", nil))

time标准库

func timeDemo() {
	//获取当前时间
	now := time.Now()
	//格式化必须使用"2006-01-02 15:04:05"
	now.Format("2006-01-02 15:04:05")

}

rand随机数

func randDemo() {
	//返回100之内的随机数。包含100
	num := rand.Intn(100)
	fmt.Println(num)
}

//init函数最先执行,获取随机数必须先初始化时间戳
func init() {
	rand.Seed(time.Now().Unix())
}

json

type BaseResponse struct {
	Code int          `json:"code"`
	Data ResponseData `json:"data"`
}

type ResponseData struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func jsonDemo() {
	br := BaseResponse{
		Code: 200,
		Data: ResponseData{
			Name: "James",
			Age:  20,
		},
	}

	//结构体序列华为json
	jsonBytes, _ := json.Marshal(&br)
	fmt.Println(string(jsonBytes))

	//json反序列化为结构体
	var br2 BaseResponse
	_ = json.Unmarshal(jsonBytes, &br2)
	fmt.Println(br2)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MoRis._

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值