Golang进阶

news2025/1/10 2:03:24

"白昼会边长,照亮心脏,让万物生长。"

一、Golang进阶

我们对golang的语法进行了一定的了解后,也算是入门了。本节的进阶篇围绕三个方向展开,Goroutine 、 Channel 、Sync。

如何理解并行与并发?

并行是指“并排行走”或“同时实行或实施”。
在操作系统中是指,一组程序按独立异步的速度执行,无论从微观还是宏观,程序都是一起执行的。对比地,并发是指:在同一个时间段内,两个或多个程序执行,有时间上的重叠(宏观上是同时,微观上仍是顺序执行)

并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

下面两张图就可以区别并发与并行;

并发:

并行:

同样,随着技术的迭代升级也有了并行+并发:

看完上面的图解。
并发的实质是针对单核CPU,它的交替调度不同任务的能力
并行的是追是针对多核CPU,它指的是多个核心同时执行多个任务的能力。
由此,单核 CPU 只能并发,无法并行。并行,只存在于多核CPU的硬件条件下。
而在多核CPU中,并发并行都会同时存在,这是提高CPU处理任务能力的重要手段

(1)Goroutine

协程,又叫做轻量级线程。这在Golang这样的编程语言中特别流行。

Go协程的特点:
1.独立的栈空间
2.共享堆空间
3. 协程调度由用户控制(进程的控制是有操作系统控制,程序员不能控制)

不管是父进程创建的子进程,还是在linuxPOSIX提供的线程库。其中的管理都是交由操作系统。因此,在程序执行的过程中,总会存在执行状态的切换(用户到内核,内核到用户)。但是,golang中的协程完完全全解决了这个问题。

协程:用户态,轻量级线程。
线程:内核态,线程可以跑多个协程。
创建一个线程栈大概需要 1MB 左右,而协程栈大概只需要几 KB或者几十KB。
package main

import (
    "fmt"
    "time"
)

func hello(i int) {
    fmt.Println("go() to hello", i)
}

func HelloRotinue() {
    for i := 0; i < 5; i++ {
        go hello(i)
    }
    time.Sleep(time.Second)
}

func main() {
    HelloRotinue()
    for i := 0; i < 5; i++ {
        fmt.Println("main() to hello", i)
        time.Sleep(time.Second)
    }
}

我们在调用打印hello的函数前面加上关键字"go"。表面,我们起一个协程来调用这个函数。

但我们此时没有设置HelloRotinue为线程,因此是等待该函数调用完时,才开始进行主线程main。

此时,只需要在该函数前加上go,这两个执行流就不会处在所谓的"阻塞"状态,而是各管各的。

什么是CSP?

CSP理念: 以通信的方式来共享内存。Go 的并发哲学,依赖于 CSP 模型。

大多数编程语言,在如何实现并发的问题上,采用的都是基于线程和内存同步访问控制。而Go 的并发编程的模型则用 goroutine 和 channel 来替代。

Goroutine 和线程类似,channel 和 mutex (用于内存同步访问控制的互斥锁)类似。

我们在linux处着重讲了,实现进程间的本质,就是让每个进程(线程)可看到同一份公共资源。而这个而资源,也叫做临界区。

通过共享内存实现通信;

通过通信共享内存;

(2)Channel

make(chan+元素类型,[缓冲大小])
例如:
无缓冲通道 make(chan int)
有缓冲通道 make(chan int,2)

比如,现在我们要执行完成一个任务。协程1发送0~9数字,协程2拿到数字后计算它们的平方,并发送给主线程,并在主线程处打印。

最后我们也可以得到结果。

(3)Sync

sync(意指Synchronize,即“同步”)为UNIX操作系统的标准系统调用,功能为将内核文件系统缓冲区的所有数据。

sync:
Package sync provides basic synchronization primitives such as mutual exclusion locks. Other than the Once and WaitGroup types, most are intended for use by low-level library routines. Higher-level synchronization is better done via channels and communication.

包同步提供了基本的同步原语,如互斥锁。除了Once和WaitGroup类型之外,大多数类型都是供低级库例程使用的。更高级别的同步最好通过信道和通信来完成。

并发安全 Lock

我们期待五个协程对x进行2000循环地自增加1

package main

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

var (
    x    int64
    lock sync.Mutex
)

func addWithLock() {
    for i := 0; i < 2000; i++ {
        lock.Lock()
        x += 1
        lock.Unlock()
    }
}

func addWithOutLock() {
    for i := 0; i < 2000; i++ {
        x += 1
    }
}

func main() {
    x = 0
    for i := 0; i < 5; i++ {
        go addWithOutLock()
    }
    fmt.Println("WithOutLock: ", x)
    time.Sleep(time.Second)

    x = 0
    for i := 0; i < 5; i++ {
        go addWithLock()
    }
    time.Sleep(time.Second)
    fmt.Println("WithLock: ", x)
}

WaitGroup

这个类里有三个比较重要的函数;

我们简简单单地用五个协程分别打印。

我们对代码进行一定的改进。让打印后的结果进行阻塞。

总结:

以上就是golang面向并发编程的相关介绍。本篇涉及的三个方面,协程(Gorotinue),信道(Channel)通过通信实现共享内存,sync关键字,支持同步互斥的并发安全操作。

本篇也就到此结束了~感谢你的阅读

祝你好运,向阳而生

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用数组实现链表、栈和队列

目录前言一、用数组实现链表1.1 单链表1.2 双链表二、用数组实现栈三、用数组实现队列前言 众所周知&#xff0c;链表可以用结构体和指针来实现&#xff0c;而栈和队列可以直接调用STL&#xff0c;那为什么还要费尽心思用数组来实现这三种数据结构呢&#xff1f; 首先&#x…

好的质量+数量 = 健康的创作者生态

缘起 CSDN 每天都有近万名创作者发表各种内容&#xff0c; 其中博客就有一万篇左右。 这个数量是非常可喜的&#xff0c;这也是 CSDN 的产品、研发运营小伙伴、和各位博主持续工作的结果。 衡量一个 IT 内容平台&#xff0c;除了数量之外&#xff0c;还有另外一些因素&#xf…

Linux——动态库

目录 制作并发布动态库 使用动态库 使用动态库程序运行时的错误 制作并发布动态库 静态库的代码在链接的时候会被拷贝进对应的可执行程序内部&#xff0c;动态库则不需要拷贝。 动态库在形成目标文件时&#xff0c;需要加一个选项 -fPIC&#xff1a;形成一个与位置无关的二…

Yocto常用术语

Yocto常用术语 Yocto是一套开源、专为嵌入式定制的编译系统&#xff0c;它提供了toolset和开发环境&#xff0c;开发人员可以利用Yocto定制基于Linux的系统。Yocto官网介绍了其常用术语&#xff0c;官网链接Yocto Project Terms&#xff0c;了解这些术语可以加深对Yocto的认识…

第五章 高级数据管理

在第4章&#xff0c;我们审视了R中基本的数据集处理方法&#xff0c;本章我们将关注一些高级话题。本章分为三个基本部分。在第一部分中&#xff0c;我们将快速浏览R中的多种数学、统计和字符处理函数。为了让这一部分的内容相互关联&#xff0c;我们先引入一个能够使用这些函数…

低功耗广域网LPWAN 8大关键技术对比

物联网被认为是继计算机、互联网之后&#xff0c;世界信息产业发展的第三次浪潮&#xff0c;它的出现将大大改变人们现有的生活环境和习惯。智能家居、工业数据采集等场景通常采用的是短距离通信技术&#xff0c;但对于广范围、远距离的连接&#xff0c;远距离通信技术不可或缺…

分享146个ASP源码,总有一款适合您

ASP源码 分享146个ASP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 146个ASP源码下载链接&#xff1a;https://pan.baidu.com/s/1HG8AMPldOPHcEmMsGnVwMA?pwdg97k 提取码&#x…

矩阵的运算、运算规则及C语言实现

在人工智能运算和原理的过程中,我们需要了解非常多的数学知识,但是大学时候学的东西已经忘的差不多了,这里我把矩阵的一系列概念总结并复习一下,以便于大家在学习AI的时候要明白很多数学计算的物理意义,当年在学习线性代数的时候,我们不一定明白这些计算的意义,现在要和…

【图卷积网络】02-谱域图卷积介绍

注&#xff1a;本文为第2章谱域图卷积介绍视频笔记&#xff0c;仅供个人学习使用 目录1、图卷积简介1.1 图卷积网络的迅猛发展1.2 回顾&#xff0c;经典卷积神经网络已在多个领域取得成功1.3 两大类数据1.4 经典卷积神经网络的局限&#xff1a;无法处理图数据结构1.5 将卷积扩展…

代码随想录算法训练营第四十八天|● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

动态规划 一、198.打家劫舍 题目&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系…

流批一体计算引擎-7-[Flink]的DataStream连接器

参考官方手册DataStream Connectors 1 DataStream连接器概述 一、预定义的Source和Sink 一些比较基本的Source和Sink已经内置在Flink里。 1、预定义data sources支持从文件、目录、socket&#xff0c;以及collections和iterators中读取数据。 2、预定义data sinks支持把数据写…

Eclipse中的Build Path

Eclipse中的Build Path简介如果修改了Build Path中的中的JRE版本&#xff0c;记得还需要同步修改Java编译器的版本&#xff0c;如下图红框所示简介 Build Path是Java工程包含的资源属性合集&#xff0c;用来管理和配置此Java工程中【除当前工程自身代码以外的其他资源】的引用…

Vision Transformer 简单复现和解释

一些我自己不懂的过程&#xff0c;我自己在后面写了demo解释。 import torch import torch.nn as nnfrom einops import rearrange, repeat from einops.layers.torch import Rearrangedef pair(t):return t if isinstance(t, tuple) else (t, t) class PreNorm(nn.Module):…

数据库系统概念 | 第七章:使用E-R模型的数据库设计 | ER图设计| ER图转化为关系模型 | 强实体和弱实体

文章目录&#x1f4da;设计过程概览&#x1f4da;实体-联系模型&#x1f407;E-R数据模型&#x1f955;实体集&#x1f955;联系集&#x1f955;属性&#x1f407;E-R图&#x1f4da;映射基数&#x1f407;二元联系集⭐️&#x1f955;一对一&#x1f955;一对多&#x1f955;多…

二叉树的顺序结构——堆的概念实现(图文详解+完整源码 | C语言版)

目录 0.写在前面 1.什么是堆&#xff1f; 2.堆的实现 2.1 堆的结构定义 2.2 函数声明 2.3 函数实现 2.3.1 AdjustUp&#xff08;向上调整算法&#xff09; 2.3.2 AdjustDown&#xff08;向下调整算法&#xff09; 2.3.3 HeapCreate&#xff08;如何建堆&#xff09; …

更多的选择器 更多伪类选择器 颜色选中时写法 被选中的第一行文字 选中第几个元素

目录更多的选择器更多伪类选择器1. first-child2. last-child3. nth-child4. nth-of-type更多的伪元素选择器1. first-letter2. first-line3. selection更多的选择器 更多伪类选择器 1. first-child 选择第一个子元素 圈住的地方意思是&#xff1a;li 的第一个子元素设置为红…

第三篇:Haploview做单倍型教程3--结果解读

大家好&#xff0c;我是邓飞&#xff0c;这里介绍一下如何使用Haploview进行单倍型的分析。 计划分为三篇文章&#xff1a; 第一篇&#xff1a;Haploview做单倍型教程1–软件安装第二篇&#xff1a;Haploview做单倍型教程2–分析教程第三篇&#xff1a;Haploview做单倍型教程…

java中对泛型的理解

那么什么是泛型泛型&#xff1a;是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。也就是说在泛型使用过程中&#xff0c;操作的数据类型被指定为一个参数&#xff0c;而这种参数类型可以用在类、方法和接口中&#xff0c;分别被称为泛型类、泛型…

【ROS2 入门】ROS2 创建工作空间

大家好&#xff0c;我是虎哥&#xff0c;从今天开始&#xff0c;我将花一段时间&#xff0c;开始将自己从ROS1切换到ROS2&#xff0c;在上几篇中&#xff0c;我们一起了解ROS 2中很多基础概念&#xff0c;从今天开始我们逐步就开始利用ROS2的特性进行开发编程了。 工作区&#…

【Linux】基础IO --- 系统级文件接口、文件描述符表、文件控制块、fd分配规则、重定向…

能一个人走的路别抱有任何期待&#xff0c;死不了 文章目录一、关于文件的重新认识二、语言和系统级的文件操作&#xff08;语言和系统的联系&#xff09;1.C语言文件操作接口&#xff08;语言级别&#xff09;1.1 文件的打开方式1.2 文件操作的相关函数1.3 细节问题2.系统级文…