并发

GO语言并发编程入门:Goroutine、Channel、Context、并发安全、GMP调度模型

GO语言并发编程入门:Goroutine、Channel、Context、并发安全、GMP调度模型

1.GO并发介绍

并发:多线程程序在一个核的cpu上运行。 并行:多线程程序在多个核的cpu上运行。 由上可知并发不是并行,并行是直接利用多核实现多线程的运行,并发则主要由切换时间片来实现”同时”运行,go可以设置使用核数,以发挥多核计算机的能力。

Go语言之所以被称为现代化的编程语言,就是因为它在语言层面已经内置了调度和上下文切换的机制。Go语言的并发编程特点主要体现在Goroutine协程和Channel通道的使用上。

  • Goroutine协程:Goroutine是Go语言中的并发执行单位。它是一种轻量级的协程,由负责整个Go程序的执行的底层系统组件Go运行时(Go runtime)调度和管理。在调用函数的时候在前面加上go关键字,就可以为一个函数创建一个goroutine。与传统的线程、协程相比,Goroutine的创建和销毁代价非常小,可以高效地创建大量的Goroutine,Goroutine 奉行通过通信来共享内存,而不是共享内存来通信。Goroutine4~5KB的栈内存占用和由于实现机制而大幅减少的创建和销毁开销是go高并发的根本原因。
  • Channel通道:通道是Goroutine之间进行安全通信和数据共享的机制。它提供了同步和互斥的功能,确保数据的有序传输和访问。通过通道,不同的Goroutine可以安全地进行数据交换和共享状态。

Goroutine是一种特殊的协程,这是因为普通的协程和操作系统线程是多对一的关系,而在Go语言中,Goroutine和操作系统线程是多对多的关系。具体来说:

  • 一个操作系统线程(OS Thread)可以对应多个Goroutine。
  • Go程序可以同时使用多个操作系统线程,这使得Go语言能够充分利用多核处理器的计算能力。
  • Go运行时调度器(Go Scheduler)负责将多个Goroutine调度到少量的操作系统线程上执行,并处理它们之间的通信。

2.GO并发编程

2.1 父子协程

在Go语言中,可以通过创建协程(Goroutine)来实现并发执行的任务。当父协程创建一个子协程时,父协程和子协程是相互独立的并发执行单元。父协程可以继续执行其他操作,而不需要等待子协程完成。子协程会在创建后立即开始执行,与父协程并发执行。父协程和子协程之间不存在直接的调用关系,它们是相互独立的执行流程。父协程的结束不会影响子协程的执行。即使父协程结束,子协程仍然可以继续执行,直到完成或被终止。父协程和子协程之间是独立的执行上下文,彼此之间的运行状态不会相互影响。 然而,需要注意的是,如果主协程(即main函数所在的协程)结束了,整个程序会终止,所有的协程也会被强制结束。这意味着如果主协程提前结束,尚未完成的子协程也会被中止。因此,在使用协程进行并发编程时,我们需要确保主协程不会过早地结束,以确保子协程能够完成任务,可以考虑采用以下方法:

  1. 使用time.Sleep使协程睡眠确保并发子协程完成
  2. 使用sync.WaitGroup等待组确保并发子协程完成

2.1.1 使用time.Sleep使协程睡眠确保并发子协程完成

time包提供了时间相关的功能,其中最常用的是time.Sleep函数,它可以让当前的Goroutine休眠一段时间。通过结合Goroutine和time.Sleep,我们可以实现协程的并发执行。

go
复制代码
package main
import (
	"fmt"
	"time"
)
func
    

新姿势!Redis中调用Lua脚本以实现原子性操作

背景:有一服务提供者Leader,有多个消息订阅者Workers。Leader是一个排队程序,维护了一个用户队列,当某个资源空闲下来并被分配至队列中的用户时,Leader会向订阅者推送消息(消息带有唯一标识ID),订阅者在接收到消息后会进行特殊处理并再次推往前端。

问题:前端只需要接收到一条由Worker推送的消息即可,但是如果Workers不做消息重复推送判断的话,会导致前端收到多条消息推送,从而影响正常业务逻辑。…

    

六种网络应用架构模式

六种网络应用架构模式

六种网络应用架构模式,以socket编程为例讲解。

一、串行化

处理请求的串行化模型。
在串行化架构中,所有的客户端连接是依次进行处理的,因为不涉及并发,多个客户端不会同时接受服务。
串行化架构最大的优势在于它的简单性。没有锁,没有共享状态,处理完一个连接之后才能处理另一个。在资源使用方面亦是如此:一个实例处理一个连接,一个萝卜一个坑,绝不多消耗资源。
串行化架构明显的劣势是不能并发操作。即便是当前连接处于空闲,也不能处理等待的连接。…

                    

PHP并发IO编程之路

并发IO问题一直是服务器端编程中的技术难题,从最早的同步阻塞直接Fork进程,到Worker进程池/线程池,到现在的异步IO、协程。PHP程序员因为有强大的LAMP框架,对这类底层方面的知识知之甚少,本文目的就是详细介绍PHP进行并发IO编程的各种尝试,最后再介绍Swoole的使用,深入浅出全面解析并发IO问题。…

并发同步知多少

找工作的时候是否经常看到要求有高并发,分布式系统的开发设计经验,或者高并发,分布式系统的开发设计经验者优先等字样,这时候情不自禁的搜索一下什么是并发,多少算高并发,再思索一下自己的经历哪些是符合这个要求的?那么什么是并发,开发中的并发是怎么处理的,简单了解一下吧。

        在介绍并发之前我们先了解一下串行和并行:
        热闹的景点,买票人很多,这时只有一个窗口售票,大家排队依次买票就可以理解为串行。
        排队人太多了,旁边又加开了几个窗口,多人在不同的窗口同时买票可以理解为并行。
    

并发之痛 Thread,Goroutine,Actor

本文基于我在2月27日Gopher北京聚会演讲整理而成,进行了一些补充以及调整。投稿给《高可用架构》公众号首发。

聊这个话题之前,先梳理下两个概念,几乎所有讲并发的文章都要先讲这两个概念:

concurrent_vs_parallel

  • 并发(concurrency) 并发的关注点在于任务切分。举例来说,你是一个创业公司的CEO,开始只有你一个人,你一人分饰多角,一会做产品规划,一会写代码,一会见客户,虽然你不能见客户的同时写代码,但由于你切分了任务,分配了时间片,表现出来好像是多个任务一起在执行。
  • 并行(parallelism) 并行的关注点在于同时执行。还是上面的例子,你发现你自己太忙了,时间分配不过来,于是请了工程师,产品经理,市场总监,各司一职,这时候多个任务可以同时执行了。
            

如何应对并发(3) – 需求裁剪

如何应对并发(1) - 关于数据索引

如何应对并发(2) - 请求合并及异步处理

 

今天讲一下,应对并发,应对海量数据请求的一个关键策略,也是很多程序员的盲区,需求裁剪。

 

这个,很多公司,技术人员会说,产品经理提需求,我们完成需求,怎么可能去裁剪需求,而且,裁剪需求会不会显得很low,说明水平很差呢。…

Web网站的几个并发量级

评价一个网站的“大小”,处于视角的不同,有很多种衡量的方法,类似文章数,页面数之类的数据非常明显,也没有什么可以争议的。但对于并发来说,争议非常之多,这里就从一个技术的角度开始,谈谈几个Web网站的数量级。

相信很多人谈论一个网站的热度,总免不了会询问日均PV,同时在线人数、注册用户数等运营数据,说实话从技术角度来说,这几个数值没有一个可以放在一起比较的——一个静态网站的PV跟一个SNS类/Web Game网站的PV根本就不是一回事。由于互联网有一个传说中的“3秒定律”,可能当下更多的网站技术指标要求1.5秒以内加载整页,或者至少可以达到阅读的标准。如果要较真什么“同时在线”,毫不客气的说,对于HTTP这类短链接的网络协议来说,在WebSocket还不普及的时代,能统计在线纯属扯淡,唯一能做的只是取个时间段,计算下访问用户而已。这些依然可以换算成QPS(Quest Per Second每秒请求数)。就并发而言,我唯一推崇的只有理论最大QPS和悲观QPS。…