GO中sync包自由控制并发示例详解

yizhihongxing

在Go语言中,sync包提供了许多同步原语和锁,可以在并发编程中实现不同的控制并发的方式。下面是关于如何自由控制并发的示例详解。

使用WaitGroup控制并发执行

使用sync包的WaitGroup类型,可以实现并发执行多个任务,并等待所有任务完成后再执行后续操作的功能。WaitGroup内部有一个计数器,每增加一个goroutine,计数器加1,每个goroutine执行完之后会对计数器减1。当计数器的值变为0时,表示所有goroutine都执行完了。下面是一个使用WaitGroup控制并发执行的示例:

package main

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

func worker(id int, wg *sync.WaitGroup) {
    fmt.Printf("Worker %d starting\n", id)
    time.Sleep(time.Second)
    fmt.Printf("Worker %d done\n", id)
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker(i, &wg)
    }
    wg.Wait()
    fmt.Println("All workers done")
}

代码中定义了一个worker函数用于模拟任务执行,该函数接收一个等待组指针作为参数,任务执行完之后会调用等待组的Done方法。在main函数中,首先创建WaitGroup实例,并使用Add方法将执行的任务数加入到等待组中,然后启动goroutine执行worker函数。最后调用等待组的Wait方法,等待所有任务执行完毕。执行结果如下:

Worker 1 starting
Worker 2 starting
Worker 3 starting
Worker 4 starting
Worker 5 starting
Worker 4 done
Worker 2 done
Worker 3 done
Worker 5 done
Worker 1 done
All workers done

使用Mutex和Cond控制并发访问共享变量

在多个goroutine并发访问共享变量时,为了避免数据竞争和不一致性问题,可以使用sync包的Mutex和Cond类型进行控制。Mutex是一种互斥锁,可以保证同时只有一个goroutine访问共享资源。Cond是在Mutex的基础上实现的条件变量,可以使goroutine在满足特定条件时才继续执行。下面是一个使用Mutex和Cond控制并发访问共享变量的示例:

package main

import (
    "fmt"
    "sync"
)

var (
    count int
    mutex sync.Mutex
    cond  *sync.Cond = sync.NewCond(&mutex)
)

func producer() {
    for i := 0; i < 10; i++ {
        mutex.Lock()
        count++
        fmt.Println("Producer: Producing ", count)
        cond.Signal()
        mutex.Unlock()
    }
}

func consumer() {
    for i := 0; i < 10; i++ {
        mutex.Lock()
        for count == 0 {
            cond.Wait()
        }
        count--
        fmt.Println("Consumer: Consuming ", count)
        mutex.Unlock()
    }
}

func main() {
    go consumer()
    go producer()
    time.Sleep(5 * time.Second)
}

代码中定义了一个共享变量count,两个goroutine分别为生产者和消费者角色。在生产者goroutine中,使用Mutex进行同步,每次将count值加1,并调用Cond的Signal方法发送信号给消费者goroutine,表示有新的资源产生。在消费者goroutine中,先获取Mutex的锁,判断count是否为0,如果是则调用Cond的Wait方法等待生产者像它发送信号,如果不是则消费资源,并将count值减1。执行结果如下:

Producer: Producing  1
Consumer: Consuming  0
Producer: Producing  1
Consumer: Consuming  0
Producer: Producing  1
Consumer: Consuming  0
Producer: Producing  1
Consumer: Consuming  0
Producer: Producing  2
Consumer: Consuming  1
Producer: Producing  3
Consumer: Consuming  2
Producer: Producing  4
Consumer: Consuming  3
Producer: Producing  5
Consumer: Consuming  4
Producer: Producing  6
Consumer: Consuming  5
Producer: Producing  7
Consumer: Consuming  6
Producer: Producing  8
Consumer: Consuming  7
Producer: Producing  9
Consumer: Consuming  8
Producer: Producing  10
Consumer: Consuming  9

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:GO中sync包自由控制并发示例详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Java 多线程并发编程_动力节点Java学院整理

    Java 多线程并发编程攻略 Java 多线程并发编程是 Java 开发中必不可少的技能,能够充分利用多核 CPU 在同一时间处理多个任务,提高程序的并发性和效率。本文将为大家介绍 Java 多线程并发编程的攻略,包括线程的创建、同步、互斥、线程池等知识点。 线程的创建 Java 中创建线程有两种方式,一种是继承 Thread 类,另一种是实现 Runnab…

    多线程 2023年5月16日
    00
  • java并发中DelayQueue延迟队列原理剖析

    Java 并发中 DelayQueue 延迟队列原理剖析 DelayQueue 是 Java 并发包中提供的一种特殊队列,它能够在一定的时间内延迟一些操作的执行。下面就来深入了解一下 DelayQueue 的原理。 DelayQueue 的基本特点 DelayQueue 继承自 java.util.concurrent.Delayed 接口,它的元素必须要实…

    多线程 2023年5月17日
    00
  • Java高并发之CyclicBarrier的用法详解

    Java高并发之CyclicBarrier的用法详解 CyclicBarrier是什么? CyclicBarrier是Java并发工具包中核心类之一,它的作用是让多个线程在执行时实现同步,等待大家都准备好之后再一起执行。与CountDownLatch类似,CyclicBarrier也可以用于控制线程的执行顺序,但是不同的是,CyclicBarrier可以让多…

    多线程 2023年5月16日
    00
  • Java请求流量合并和拆分提高系统的并发量示例

    针对“Java请求流量合并和拆分提高系统的并发量示例”,我们可以分为以下几个步骤来进行完整的攻略说明。 1. 了解请求流量合并和拆分的概念 首先需要明确的是,请求流量合并和拆分是一种系统设计上的优化方法,通过对同一业务请求的合并或拆分,来提高系统的并发量和性能。 具体地,请求流量合并是指将多个业务请求进行合并处理,最终返回一个合并后的响应数据,以此来减少网络…

    多线程 2023年5月16日
    00
  • 如何在Python中编写并发程序

    一、什么是并发编程 并发编程是指程序同时执行多个任务的一种编程方式。在Python中,这通常通过多线程、多进程和协程来实现。 在多线程、多进程和协程中,每个任务都是独立的,它们可以在不影响其他任务的情况下并发执行,从而提高程序的效率。 二、如何在Python中编写多线程程序 使用threading模块创建线程 Python中内置的threading模块提供了…

    多线程 2023年5月17日
    00
  • Java并发LinkedBlockingQueue源码分析

    Java并发LinkedBlockingQueue源码分析 简单介绍 LinkedBlockingQueue是Java并发包中提供的一个阻塞队列实现,它支持在队列两端添加或取出元素,并具有阻塞功能。具体来说,当队列为空时,从队列尾部加入元素的操作将被阻塞;当队列满时,从队列头部取出元素的操作将被阻塞。 源码解析 内部类:Node 在LinkedBlockin…

    多线程 2023年5月16日
    00
  • Java并发之原子性 有序性 可见性及Happen Before原则

    Java并发之原子性、有序性、可见性及Happen Before原则 原子性 Java中的原子性是指一个操作或者多个操作,要么全部都执行并且执行的过程不会被任何因素中断,要么就全部都不执行。在Java中,原子性可以通过synchronized和Lock关键字实现。除此之外,Java实现了java.util.concurrent.atomic包,提供了一系列原…

    多线程 2023年5月17日
    00
  • C#的并发机制优秀在哪你知道么

    C#的并发机制是其作为一门现代编程语言的一个重要特性之一。并发编程可以提高代码的性能,在不影响程序正确性的同时应用多核处理器。 C#的并发机制优秀在以下几个方面: 多线程支持:C#提供了多个构建线程(Thread)的方式,例如通过继承Thread类、通过创建Thread实例、使用ThreadPool等。通过这些方式可以生成多个线程来执行耗时的操作。在同时执行…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部