Go语言之并发编程练习,GO协程初识,互斥锁,管道:channel的读写操作,生产者消费者

GO协程初识

package main

import (
	"fmt"
	"sync"
	"time"
)

func read() {
	defer wg.Done()
	fmt.Println("read start")
	time.Sleep(time.Second * 3)
	fmt.Println("read end")
}

func listenMusci() {
	defer wg.Done()
	fmt.Println("listenMusci start")
	time.Sleep(time.Second * 5)
	fmt.Println("listenMusci end")
}

var wg sync.WaitGroup //声明一把锁,同步的一个等待锁,本质是一个计时器,所有的进程都可以共享

func main() {
	start := time.Now().Unix()

	wg.Add(2)
	go read()        //开启GO并发
	go listenMusci() //开启GO并发

	wg.Wait() //计数器为0继续执行

	//time.Sleep(time.Second * 10) //将main主线程阻塞下

	end := time.Now().Unix()
	fmt.Println(end - start)
}

输出结果:
在这里插入图片描述

互斥锁

package main

import (
	"fmt"
	"sync"
	"time"
)

/*
	互斥锁!!!
互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有
一个goroutine可以访问共享资源。Go语言中使用sync包的Mutex类型来实现互斥锁。

使用互斥锁能够保证同一时间有且只有一个goroutine进入临界区,
其他的goroutine则在等待锁;当互斥锁释放后,等待的goroutine才可以获取锁进入临界区,
多个goroutine同时等待一个锁时,唤醒的策略是随机的。
*/
var wg sync.WaitGroup //声明一把锁,同步的一个等待锁,本质是一个计时器,所有的进程都可以共享
var lock sync.Mutex

var x = 0

func add() {
	defer wg.Done()

	//加锁,互斥锁
	lock.Lock()
	x++
	lock.Unlock()

	println(x)
	time.Sleep(time.Second * 10) //
}
func main() {
	wg.Add(100)
	for i := 0; i < 100; i++ {
		go add()
	}
	wg.Wait() //计数器为0继续执行

	fmt.Println(x)
}

管道:channel的读写操作

package main

import (
	"fmt"
	"reflect"
)

/*
	管道:channel的读写操作!!!
	chan是go的协程之间通信的数据类型(引用类型)
	没有索引的概念,取完第一个才能取第二个
*/
func 声明一个管道() {
	//声明一个管道
	var ch = make(chan int, 3)
	//插入值
	ch <- 12
	ch <- 13
	ch <- 15
	//取值
	fmt.Println(<-ch)
	fmt.Println(<-ch)
	fmt.Println(<-ch)
}

//声明一个结构体
type Msg struct {
	content string
	from    string
}

func main() {
	var ch = make(chan interface{}, 6)
	ch <- "hello"
	ch <- true
	ch <- 15
	ch <- Msg{content: "from kegog", from: "中国北京"}
	one := <-ch
	fmt.Println(one, reflect.TypeOf(one))

	fmt.Println(<-ch)

	fmt.Println(<-ch)

	//fmt.Println(<-ch)
	fmt.Println((<-ch).(Msg).content)
}

管道关闭后不能再写入值了

package main

import "fmt"

/*
	管道的关闭与循环!!
*/
func 管道关闭后不能再写入值了() {
	ch3 := make(chan int, 10)
	ch3 <- 1
	ch3 <- 2
	ch3 <- 3

	close(ch3)
	fmt.Println(<-ch3)
	ch3 <- 4
}
func main() {
	管道关闭后不能再写入值了()
}

遍历管道之前要先关闭管道close

package main

import (
    "fmt"
    "time"
)

func main() {

    ch := make(chan int, 10)
    ch <- 1
    ch <- 2
    ch <- 3

    // 方式1
    go func() {
        time.Sleep(time.Second * 10)
        ch <- 4

    }()

    for v := range ch {

        fmt.Println(v, len(ch))
        // 读取完所有值后,ch的sendq中没有groutine
        if len(ch) == 0 { // 如果现有数据量为0,跳出循环
            break
        }
    }

    close(ch)
    for i := range ch {
        fmt.Println(i)
    }

}

生产者消费者

package main

import (
	"fmt"
	"sync"
	"time"
)

func producer(ch chan<- int) {
	defer wg.Done()
	for i := 1; i < 11; i++ {
		time.Sleep(time.Second)
		ch <- i
		fmt.Println("生产了:", i)
	}
	close(ch)
}

func consumer(ch <-chan int) {
	defer wg.Done()
	for i := range ch {
		fmt.Println("消费了:", i)
	}
}

var wg sync.WaitGroup

func main() {
	ch := make(chan int, 100)

	wg.Add(2)
	go producer(ch)
	go consumer(ch)

	wg.Wait()
	fmt.Println("process end")
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/39738.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在云计算环境中,保护Java应用程序可用的有效措施和工具

云计算&#xff08;Cloud&#xff09;技术是近年来计算机科学的一个重要突破。大多数组织已经通过将自己的应用程序移入云平台而获益。不过&#xff0c;如何保证应用程序在第三方服务器上的安全性&#xff0c;是一项艰巨的挑战。 在本文中&#xff0c;我们将重点讨论Java&…

长沙打造“全球研发中心城市”,智能网联产业如何交卷?

作者 | 魏启扬 来源 | 洞见新研社 知乎上有一个浏览超百万的热门问题——“大家怎么看待长沙这个城市&#xff1f;” 答主“星球研究所”的回答获得了高赞&#xff0c;“这是一个天性如火的城市”。 网红城市的外衣下&#xff0c;从湖南卫视的综艺节目&#xff0c;到网红美…

数据结构--栈

一、栈 数组是一种连续存储、随机访问的线性表&#xff0c;链表属于分散存储、连续访问的线性表。它们每个数据都有其相对位置&#xff0c;有至多一个直接前驱和之多一个直接后继。栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;也属于线性表&#xff0c…

Fortinet Accelerate 2023·中国区巡展收官丨让安全成就未来

7月18日&#xff0c;2023 Fortinet Accelerate Summit在上海成功举办&#xff01;这亦象征着“Fortinet Accelerate2023中国区巡展”圆满收官。Fortinet携手来自多个典型行业的百余位代表客户&#xff0c;以及亚马逊云科技、Telstra - PBS 太平洋电信、Tenable等多家生态合作伙…

字幕切分视频

Whisper 仓库地址&#xff1a; https://github.com/openai/whisper 可用模型信息&#xff1a; 测试视频&#xff1a;18段&#xff0c;总共447S视频&#xff08;11段前&#xff1a;有11段开头有停顿的视频&#xff09; Tiny: 跑完&#xff1a;142S &#xff0c;11段前&#xf…

学习opencv.js之基本使用方法(读取,显示,灰度化,边缘检测,特征值点检测)

opencv.js是什么 OpenCV.js 是 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;的 JavaScript 版本。OpenCV 是一个广泛使用的计算机视觉和图像处理库&#xff0c;提供了一系列功能强大的算法和工具&#xff0c;用于处理图像、视频、特征提取、对象识别等…

无虚拟 DOM 版 Vue 进行到哪一步了?

前言 就在一年前的 Vue Conf 2022&#xff0c;尤雨溪向大家分享了一个非常令人期待的新模式&#xff1a;无虚拟 DOM 模式&#xff01; 我看了回放之后非常兴奋&#xff0c;感觉这是个非常牛逼的新 feature&#xff0c;鉴于可能会有部分人还不知道或者还没听过什么是 Vue 无虚…

智能电表数据采集器

智能电表数据采集器是一种用于采集智能电表数据的设备&#xff0c;它可以将智能电表的数据传输到远程服务器上&#xff0c;以便进行数据分析和监控。智能电表数据采集器的主要功能是采集智能电表的实时数据&#xff0c;并将其发送到远程服务器上&#xff0c;从而实现对智能电表…

C语言--程序环境和预处理

翻译环境 C语言的代码是文本信息&#xff0c;对于计算机来说无法直接理解&#xff0c;需要通过翻译环境进行翻译成二进制信息&#xff1b; 我们在写代码的时候&#xff0c;一般都会写在一个源文件中&#xff0c;这时候我们就使用我们的编译器(VS)将其转换为机器代码&#xff0…

关于GPT、AI绘画、AI提词器等AI技术的探讨

目前的AI潮流非常火热&#xff0c;CHATGPT可谓是目前大模型人工智能的代表&#xff0c;刚开始听说chatGPT可以写代码&#xff0c;写作&#xff0c;写方案&#xff0c;无所不能。还有AI绘画也很&#xff2e;&#xff22;作为一个程序员&#xff0c;为了体验这些&#xff21;&…

node基于express+mongodb项目的整体结构搭建和逻辑抽离

一、为什么需要逻辑抽离 这是我用express实现的一个缩减版的注册功能,如下&#xff1a; app.js const express require("express"); const app express();// 连接数据库 const mongoose require("mongoose"); // 连接数据库myTest mongoose.connect(…

【云原生】k8s之Ingress

1.Ingress的相关知识 1.1 Ingress的简介 service的作用体现在两个方面&#xff0c;对集群内部&#xff0c;它不断跟踪pod的变化&#xff0c;更新endpoint中对应pod的对象&#xff0c;提供了ip不断变化的pod的服务发现机制&#xff1b;对集群外部&#xff0c;他类似负载均衡器…

【剧前爆米花--web】HTTP协议格式详解以及构造

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaEE初阶》 文章分布&#xff1a;这是一篇关于HTTP协议的文章&#xff0c;在这篇文章中我会说明HTTP协议格式以及相关的构造&#xff0c;希望对你有所帮助&#xff01; 目录 HTTP协议 HTTP协议格式 HTTP请求 HTTP响应详情…

前端基本功 用 React Hooks + Antd 实现一个 Todo-List

背景 使用 React Hooks 以及组件库 Antd 来实现一个可以 增删 标记是否完成 的 todo-list 思路 要实现一个 todo-list 首先想到用 useState 维护一个状态数组来保存当前 list &#xff0c;还要用一个状态维护添加框中的内容 const [todos, setTodos] useState(initialValu…

如何用双指针法解决力扣“反转单词前缀”问题

本篇博客会讲解力扣“2000. 反转单词前缀”的解题思路&#xff0c;这是题目链接。 本题的思路是&#xff1a;先调用strchr函数&#xff0c;在字符串word中查找字符ch&#xff0c;若找到了&#xff0c;则会返回一个非空指针p&#xff0c;指向ch在word中的位置。为了反转从word到…

【UE4 塔防游戏系列】10-防御塔升级

目录 效果 步骤 一、根据防御塔等级修改子弹伤害 二、根据防御塔等级修改子弹速度 三、根据防御塔等级修改检测半径 四、根据防御塔等级修改子弹颜色 五、根据防御塔等级修改换弹时间 效果 步骤 一、根据防御塔等级修改子弹伤害 1. 打开“TowerBaseBullet_Child”&…

搭建Redis分片集群

说明&#xff1a;单体Redis有许多问题&#xff0c;可通过Redis数据持久化、搭建主从集群、哨兵和Redis分片集群解决单体Redis数据丢失、高并发、数据恢复和海量数据存储的问题。前三个参考http://t.csdn.cn/6pp2F、http://t.csdn.cn/o9u0S&#xff0c;本问介绍如何创建Redis分片…

http连接处理(下)(四)

1.结合代码分析请求报文响应 下面我们将介绍服务器如何响应请求报文&#xff0c;并将该报文发送给浏览器端。首先介绍一些基础API&#xff0c;然后结合流程图和代码对服务器响应请求报文进行详解。 基础API部分&#xff0c;介绍stat、mmap、iovec、writev。 流程图部分&…

数据结构--时间复杂度与空间复杂度

数据结构–时间复杂度与空间复杂度 文章目录 数据结构--时间复杂度与空间复杂度时间复杂度一、什么是时间复杂度二、具体实例1.大O的渐进表示法2.二分查找的时间复杂度 空间复杂度一、什么是空间复杂度二、具体实例总结 时间复杂度 一、什么是时间复杂度 在计算机科学中&…

微信小程序-地图上的图标计算旋转值朝向经纬度计算

废话不多说&#xff0c;开整 // 参数为寄件人经纬度和收件人经纬度 // 根据寄收件人经纬度弧度π进行rotate旋转计算 const getRotate (po1, po2) > {if (!(po1 && po2)) return 0const lng_a po1.longitudeconst lat_a po1.latitudeconst lng_b po2.longitud…