当前位置: 首页 > news >正文

类似 wordpress 建站黑色大气金融投资企业网站模板

类似 wordpress 建站,黑色大气金融投资企业网站模板,h5商城网站建站,wordpress themepath总述 这篇文章#xff0c;我想谈一谈自己对于并发变成的理解与学习。主要涉及以下三个部分#xff1a;goroutine#xff0c;channel以及lock 临界区 首先#xff0c;要明确下面两组概念 并发和并行 并行#xff1a;指几个程序每时每刻都同时进行 并发#xff1a;指…总述 这篇文章我想谈一谈自己对于并发变成的理解与学习。主要涉及以下三个部分goroutinechannel以及lock 临界区 首先要明确下面两组概念 并发和并行 并行指几个程序每时每刻都同时进行 并发指在单位时间内同时运行 go的并发模型在内存共享方面有点类型SMP模型 相似之处 多处理器利用 SMPSMP 系统利用多个处理器或核心来并行处理任务系统中的所有处理器共享同一内存空间。Go Go 通过 goroutines 和调度器来利用多个处理器能够在多核处理器上并行执行多个 goroutine。Go 的调度器会将 goroutine 分配到可用的处理器上从而实现并行计算。 共享内存 SMP所有处理器访问同一内存空间可以直接共享数据。Go goroutines 可以通过共享内存进行通信虽然 Go 提供了通道channels作为主要的同步和通信机制但共享内存仍然是可能的。Go 的同步机制如互斥锁mutex和原子操作帮助避免数据竞争和保持一致性。 不同之处 并发模型 SMPSMP 更多地关注于物理硬件层面的多处理器架构和资源共享不直接涉及编程模型。Go Go 语言提供了一种高层次的并发编程模型通过 goroutines 和 channels 来简化并发编程。Go 的调度器负责将 goroutines 映射到系统线程和处理器上程序员可以更高效地编写并发程序而不需要直接管理线程。 调度和管理 SMP在 SMP 系统中操作系统负责调度和管理线程确保线程能够在多个处理器上运行。Go Go 运行时提供了一个轻量级的调度器称为 GOMAXPROCS管理 goroutines 的执行。Go 的调度器将 goroutines 调度到系统线程上而不是直接由操作系统的线程调度机制来管理。 编程模型 SMP编程模型通常需要考虑线程同步、数据竞争和缓存一致性等底层细节。Go Go 的并发模型通过 goroutines 和通道提供了较高的抽象程序员不需要直接处理线程和锁的细节使并发编程更为简洁和安全。 总的来说虽然 Go 的并发模型与 SMP 在利用多处理器的并行能力上有相似之处但 Go 的模型更专注于简化并发编程而 SMP 更加关注底层的处理器和内存管理。 协程 进程 线程 1. 进程Process 定义 进程是计算机中正在运行的程序的实例具有独立的地址空间、资源和执行上下文。每个进程都有自己的内存空间、文件描述符和其他系统资源。 特点 资源独立每个进程有独立的内存空间进程间的通信需要使用 IPC进程间通信机制如管道、共享内存等。开销大创建和销毁进程的开销相对较大因为涉及内存分配和资源管理。 2. 线程Thread 定义 线程是进程中的一个执行单元是程序执行的最小单位。一个进程可以包含多个线程它们共享进程的地址空间和资源。 特点 共享资源同一进程中的线程共享进程的内存和资源因此线程间的通信比进程间的通信更为高效。开销小线程的创建和销毁比进程要轻量因为不需要为每个线程分配独立的地址空间。 3. 协程Coroutine 定义 协程是一种用户级的轻量级线程可以在程序中暂停和恢复执行。协程通常在同一线程中切换由程序控制而不是由操作系统调度。 特点 高效由于协程是由程序员控制的切换开销相对较小适合处理高并发场景。共享同一线程协程通常在同一线程内运行之间的切换非常快速适合执行 I/O 密集型任务。 区别总结 特性进程线程协程定义程序的独立实例进程内的执行单元用户级的轻量级线程内存独立的内存空间共享进程内的内存共享线程内的内存开销高较低低调度由操作系统调度由操作系统调度由程序控制通信复杂需要 IPC简单共享内存更简单通过函数调用应用场景适合 CPU 密集型任务适合多任务并发处理适合高并发的 I/O 密集型任务 适用场景 进程适用于需要高度隔离的任务比如服务器、桌面应用等。线程适合需要共享资源的任务如 GUI 应用程序的事件处理、网络服务等。协程适合 I/O 密集型的应用如网络爬虫、异步处理等能够有效管理大量并发任务。 Go程的使用 go语言使用的是共享内存(与传统的共享模型不同的是go语言与大多编程语言一样允许加锁来保证线程安全)的并发模式使用go关键字可以启动一个go程先后顺序是随机的、可互换的不同的go程之间可以通过通道来传输数据使用锁或者sync包中的方法可以控制进程的顺序有点类似于阶段内随机、总体分阶段进行。 Goroutine 在go语言中并发性是一种语言天然支持简洁而容易实现的。 两种调用 实现一个“go程”最常见的方法在正常的函数调用之前加上“go”关键字即可 for i : 0; i 5; i {wg.Add(1)//暂且忽略这一行go work(wg)}在go中无法控制go程执行的先后顺序也就是说这些go程的先后顺序是随机的。 此外还有一种方法是使用闭包函数的直接调用 go func() { //使用go 直接将这个函数作为一个goroutine来运行defer fmt.Println(A defer)func() {defer fmt.Println(B defer)runtime.Goexit() //退出这个goroutine//return 退出内层匿名函数fmt.Println(A)}()}()Go程的常见配套方法 前置defer()标记结束 func Run() {defer fmt.Println(子进程结束了)for i : 0; i 10; i {fmt.Println(这是子进程的第, i, 个循环)time.Sleep(1 * time.Second)} }利用defer的特性我们可以在go触发进程的函数结束之后达到某种效果比如sync.WaitGroup.Done() time.Sleep(* time.Second)收尾 goroutine可能的切换点 I/Oselectchannel等待锁函数调用有时runtime.Gosched() Channel channel是一个通道是用来实现两个进程之间的通信的本质上是一个队列的数据结构。 channel实现了goroutine两个进程之间的通信 chan2 : make(chan int, 10) make(chan Type, capacity)有缓冲通道 chan1 : make(chan int) //make(chan Type)无缓冲通道向通道中读写数据 //向管道中写入数据 channel - value 发送//从管道中读取数据 - channel 接收并将其丢弃 x : - channel 接收并赋值 x , ok : - channel 接收并赋值ok为false表示channel已关闭两种通道的解释 下面两个是刘丹冰老师对于无缓冲通道和有缓冲通道的形象解释 无缓冲通道 有缓冲通道 实例 func test1() {defer fmt.Println(主进程已经结束)//创建一个无缓冲channelc : make(chan int)go func() {defer fmt.Println(子进程已经结束)fmt.Println(正在进行)num : 666fmt.Println(子进程中数据的值为, num)c - num}()num : -c //通过通道将子进程的数据捕捉到主进程fmt.Println(主进程捕捉到的子进程数据 , num) }Lock 锁的使用包含在sync包里面分为互斥锁(Mutex)、读写锁(RWMutex)、等待组(WaitGroup、一次性锁Once和条件变量Cond。这是为了解决在Go代码中可能会存在多个goroutine同时操作一个资源临界区以及这种情况下发生的竞态问题数据竞态。这篇文章只涉及前面两个后续的在sync包中解释。 互斥锁Mutex类型 互斥锁只能被一个goroutine同时持有。如果另一个goroutine试图获取一个已被持有的互斥锁它将被阻塞直到持有锁的goroutine释放锁。使用互斥锁能够保证同一时间有且只有一个goroutine进入临界区其他的goroutine则在等待锁当互斥锁释放后等待的goroutine才可以获取锁进入临界区多个goroutine同时等待一个锁时唤醒的策略是随机的。 案例 package mainimport (fmtsynctime )var (sharedValue intmu sync.Mutex // 创建一个互斥锁 )func increment(wg *sync.WaitGroup, id int) {defer wg.Done() // 完成任务时调用 Done()for i : 0; i 5; i { // 为了简化输出将循环次数减少到5次mu.Lock() // 获取锁fmt.Printf(Go程编号 %d: 将共享变量 sharedValue 的值从 %d 增加\n, id, sharedValue)sharedValue // 访问和修改共享变量time.Sleep(100 * time.Millisecond) // 模拟其他工作增加延迟以便观察输出fmt.Printf(Go程编号 %d: 将共享变量 sharedValue 的值增加到 %d \n, id, sharedValue)mu.Unlock() // 释放锁} }func main() {var wg sync.WaitGroupwg.Add(2) // 添加两个 goroutine 的等待go increment(wg, 1) // 创建第一个 goroutine并传递ID 1go increment(wg, 2) // 创建第二个 goroutine并传递ID 2wg.Wait() // 等待所有 goroutine 完成fmt.Printf(最终的共享变量值: %d\n, sharedValue) } 运行结果 Go程编号 2: 将共享变量 sharedValue 的值从 0 增加 Go程编号 2: 将共享变量 sharedValue 的值增加到 1 Go程编号 2: 将共享变量 sharedValue 的值从 1 增加 Go程编号 2: 将共享变量 sharedValue 的值增加到 2 Go程编号 1: 将共享变量 sharedValue 的值从 2 增加 Go程编号 1: 将共享变量 sharedValue 的值增加到 3 Go程编号 1: 将共享变量 sharedValue 的值从 3 增加 Go程编号 1: 将共享变量 sharedValue 的值增加到 4 Go程编号 2: 将共享变量 sharedValue 的值从 4 增加 Go程编号 2: 将共享变量 sharedValue 的值增加到 5 Go程编号 2: 将共享变量 sharedValue 的值从 5 增加 Go程编号 2: 将共享变量 sharedValue 的值增加到 6 Go程编号 1: 将共享变量 sharedValue 的值从 6 增加 Go程编号 1: 将共享变量 sharedValue 的值增加到 7 Go程编号 1: 将共享变量 sharedValue 的值从 7 增加 Go程编号 1: 将共享变量 sharedValue 的值增加到 8 Go程编号 2: 将共享变量 sharedValue 的值从 8 增加 Go程编号 2: 将共享变量 sharedValue 的值增加到 9 Go程编号 1: 将共享变量 sharedValue 的值从 9 增加 Go程编号 1: 将共享变量 sharedValue 的值增加到 10 最终的共享变量值: 10这个程序说明了Lock()将go程锁住这时候只有一个进程可以更改变量的值直到这个进程结束后才能有其他进程一起竞争这个变量值的使用。 锁的影响范围 在 mu.Lock() 和 mu.Unlock() 之间的代码这些代码块中的所有操作都被保护。只有持有锁的 goroutine 可以执行这些操作。在 mu.Unlock() 之后的代码锁的释放意味着其他等待的 goroutine 现在可以获取锁并继续执行它们的操作。锁不再影响 mu.Unlock() 之后的代码块。 读写互斥锁RWMutex类型 读写锁允许多个goroutine同时读取受保护的数据但只允许一个goroutine同时写入受保护的数据。 每个进程都可以获得读锁拿到之后都可以读。但是写锁只有一把谁拿到谁写。所以很明显读写锁非常适合读多写少的场景如果读和写的操作差别不大读写锁的优势就发挥不出来。 案例如下 package mainimport (fmtsynctime )var (sharedValue intrwMutex sync.RWMutex )// 读操作 func read(id int) {rwMutex.RLock() // 获取读锁fmt.Printf(Goroutine %d: Reading sharedValue: %d\n, id, sharedValue)time.Sleep(100 * time.Millisecond) // 模拟读取操作rwMutex.RUnlock() // 释放读锁 }// 写操作 func write(id int, value int) {rwMutex.Lock() // 获取写锁fmt.Printf(Goroutine %d: Writing sharedValue from %d to %d\n, id, sharedValue, value)sharedValue valuetime.Sleep(200 * time.Millisecond) // 模拟写操作rwMutex.Unlock() // 释放写锁 }func main() {var wg sync.WaitGroup// 启动多个读操作for i : 1; i 5; i {wg.Add(1)go func(id int) {defer wg.Done()read(id)}(i)}// 启动多个写操作for i : 1; i 3; i {wg.Add(1)go func(id int) {defer wg.Done()write(id, id*10)}(i)}// 再启动一些读操作for i : 6; i 10; i {wg.Add(1)go func(id int) {defer wg.Done()read(id)}(i)}wg.Wait()fmt.Printf(最终共享值为: %d\n, sharedValue) }运行结果 Goroutine 1: Reading sharedValue: 0 Goroutine 2: Reading sharedValue: 0 Goroutine 2: Writing sharedValue from 0 to 20 Goroutine 8: Reading sharedValue: 20 Goroutine 9: Reading sharedValue: 20 Goroutine 4: Reading sharedValue: 20 Goroutine 3: Reading sharedValue: 20 Goroutine 6: Reading sharedValue: 20 Goroutine 7: Reading sharedValue: 20 Goroutine 5: Reading sharedValue: 20 Goroutine 10: Reading sharedValue: 20 Goroutine 1: Writing sharedValue from 20 to 10 Goroutine 3: Writing sharedValue from 10 to 30 最终共享值为: 30从这里面我们可以看出来读操作的进程是没有什么先后顺序的完全随机的比如89436这几个进程完全是竞争的关系而写操作之间也是相互竞争的。但是我们不难发现对于读取操作他们使用的是读锁因此这个竞争是随机的但是写锁很明显是有着先后顺序的这点从前后值的变化就可以看出即前面一个写进程结束之后后面一个写进程才能继续。 后续的三个锁在sync包中有详解。
http://www.dnsts.com.cn/news/79997.html

相关文章:

  • 建网站公司 快云网站更换ip地址
  • 浅谈网站建设无锡做网站的公司
  • 2002年做网站多少钱设计公司怎么开
  • 长春百度网站排名优化程序wordpress
  • wordpress模板 门户网站喜欢做网站
  • 旅游网站项目计划书广告公司名字怎么取好
  • 一品猪网站开发客户关系管理的重要性
  • 网站流量利用wordpress wp config
  • 网站不备案做电影网站深圳建筑业网站建设
  • php网站开发cmswordpress版本查看
  • 山西龙采网站建设合同互联网公司排名500强
  • 龙华网站建设方案案例做本地网站需要的软件
  • 怎样推广网站网站平台建设方案
  • 调用wordpress数据库连接为什么要做seo
  • 朝阳网站建设开发南京网站开发南京乐识不错
  • 做艺术品拍卖的网站彩票网站的统计怎么做
  • 网站建设会碰到什么问题门户网站建站要求
  • 天猫交易网站郑州冬青街 网站建设
  • 齐装网网站优化潍坊
  • 自己做网站striwordpress 建筑主题
  • 免费素材网站psd互动营销策略
  • 如何构建网站河南省中原建设有限公司网站
  • 网站维护的工作内容步骤手机怎样建立网站
  • 做旅游网站的yi中小企业网站提供了什么
  • 做网站推销的如何谈客户省级示范校建设网站
  • 外贸网站模板推荐html5个人网页完整代码
  • 济南行知网站建设建设一个网站的所有代码
  • 网站建设毕业设计论文贸易公司如何做英文网站
  • asp.net做网站后台wordpress如何修改代码
  • 台州网站建设公司哪个好vps看网站蜘蛛