首页 > 编程语言 >go并发编程系列四:线程分组及控制线程的执行

go并发编程系列四:线程分组及控制线程的执行

时间:2023-09-02 16:23:23浏览次数:39  
标签:张三 concurrent 李四 线程 控制线 王五 go

背景:在上一篇中,作为班主任的你,对班级的管理初见成效,但理想和现实总有差距,理想情况下,从接手一个调皮的班级到班级的管理井井有条,是从0到1的跨越,没有中间的过渡阶段,然而,现实是:班级里少不了调皮的学生,对于这样的情况,应该怎么办呢?这篇文章讲解的正是现实中从0到1的过渡阶段,本文仅以讲解技术为出发点,不代表教育观点。

有一个万不得已的办法是:听话的学生和调皮的学生互不干扰。

对应为线程,就是对线程进行分组,按组执行。

在我们的假定场景中,张三、李四是听话的学生,自然是一组,王五是一组,三个学生需要完成一组任务,同时我们希望同一组的张三、李四共同完成任务。

我们把上述业务场景拆分为技术片段:张三、李四分组 + 张三、李四共同完成任务 + 王五单独一组 + 王五独自完成自己的任务

分组的概念很好理解,那么:张三、李四共同完成任务意味着什么呢?直白的说,就是张三、王五对应的线程不再各自持有互斥锁,变为普通线程,以便可以交替执行。

为了进一步演示这个场景,我们引入了任务的工具类:init.go,代码如下:

package concurrent

var task = map[int]string{1:"起床", 2:"洗漱", 3:"吃饭"} // 班主任规定的一组任务

 

模拟班级的代码如下:

package concurrent

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

// 在这个例子里,我们希望王五不要捣乱,等张三和李四完成任务,王五再出现
// 即:张三和李四对应的线程先执行,王五对应的线程最后执行

var mutexImprove sync.Mutex // 创建一个互斥锁

func ThreadMutexImporveZhangSan(wg *sync.WaitGroup) {
    defer wg.Done()

    for i :=1; i <= 3; i++ {
        fmt.Println("张三:", task[i])
        time.Sleep(time.Millisecond * 500)
    }
}

func ThreadMutexImproveLiSi(wg *sync.WaitGroup) {
    defer wg.Done()

    for i := 1; i <= 3; i++ {
        fmt.Println("李四:", task[i])
        time.Sleep(time.Millisecond * 500)
    }
}

func ThreadMutexImproveWangWu() {
    for i := 1; i <= 3; i++ {
        fmt.Println("王五*:", task[i])
        time.Sleep(time.Millisecond * 500)
    }
}

 

为了适应线程分组,main.go的代码需要引入sync.WaitGroup,代码如下:

    wgImprove.Add(2)
    go concurrent.ThreadMutexImporveZhangSan(&wgImprove)
    go concurrent.ThreadMutexImproveLiSi(&wgImprove)
    wgImprove.Wait()
    go concurrent.ThreadMutexImproveWangWu()

此时,执行代码,可以看到张三、李四是一组的,并且是交替执行,王五是独立的,这也就意味着我们完成了班级的管理目标。

TRANSLATE with x English
Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian  
  TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back

标签:张三,concurrent,李四,线程,控制线,王五,go
From: https://www.cnblogs.com/jamstack/p/17673803.html

相关文章

  • go并发编程系列三:线程的顺序执行
    背景:在go并发编程系列二,你作为班主任,接手了有三个学生的班级,现状是这三个学生很调皮,看起来乱糟糟的,三个学生就是三个线程,怎么变的有序呢?答案是:给线程加锁!加锁需要使用go标准包的sync.Mutex,这是一个互斥锁。给线程加锁的代码:packageconcurrentimport("fmt""sync"......
  • go并发编程系列二:线程的并发执行
    新建concurrent文件夹,在该文件夹下创建concurrent.go,代码如下:packageconcurrentimport("fmt""time")funcThreadZhangSan(){fori:=1;i<=3;i++{fmt.Println("张三:",i)time.Sleep(time.Millisecond*50......
  • mongodb副本集(非仲裁模式)修改各节点ip(update方式)
    环境:OS:Centos7mongodb:5.0当前的ip变更后的ip192.168.1.108192.168.1.105   PRIMARY192.168.1.109192.168.1.106   SECONDARY192.168.1.110192.168.1.107   SECONDARY 1.查看当前的集群登录一个节点上查......
  • go并发编程系列:一、建立线程
    在go语言中,使用线程的格式是:go函数名当然,你也可以使用匿名函数,我们建立三个线程,代码如下:gotest1()gotest2()gofunc(){}是不是很简单?在下一系列中,我们将扩展这三个线程,进一步讲解go的并发编程!TRANSLATEwithxEnglishArabicHebrewPolishBulgar......
  • 系统编程-线程池
    工程背景考虑这么一个情况:为应对某场景的实际需求,要在程序中创建大量线程,并且这些线程的数量和生命周期均不确定,可能方生方死,也可能常驻内存,如何在满足其要求的同时,尽可能降低系统负载?一个基本事实是,线程的创建和销毁都是需要额外的系统资源的,如果线程的生命周期很短,那么相对于......
  • 微服务架构|go-zero 的自适应熔断器
    原文链接:go-zero的自适应熔断器上篇文章我们介绍了微服务的限流,详细分析了计数器限流和令牌桶限流算法,这篇文章来说说熔断。熔断和限流还不太一样,限流是控制请求速率,只要还能承受,那么都会处理,但熔断不是。在一条调用链上,如果发现某个服务异常,比如响应超时。那么调用者为了避免......
  • go 1.21:cmp
    标准库cmp原文在这里go1.21新增cmp包提供了与有序变脸比较相关的类型和函数。Ordered定义如下:typeOrderedinterface{ ~int|~int8|~int16|~int32|~int64| ~uint|~uint8|~uint16|~uint32|~uint64|~uintptr| ~float32|~float64| ~string......
  • Django系统报错总结 1
    Django系统报错总结1 本章节,继续总结前面商品系统编写中遇到的报错问题TypeError:Product()gotunexpectedkeywordarguments:'update_time','seller'因为在Product类中没有定义参数update_time和seller。要解决这个问题,你需要确保在Product类中添加这些参数的定义。......
  • 《C++并发编程实战》读书笔记(1):线程管控
    1、线程的基本管控包含头文件<thread>后,通过构建std::thread对象启动线程,任何可调用类型都适用于std::thread。voiddo_some_work();structBackgroundTask{voidoperator()()const;};//空的thread对象,不接管任何线程函数std::threadt1;//传入普通函数std::thr......
  • django+drf开发一些个人的标准化
    最近在改造一下个人的开发风格。特分享一下。子应用我一般放在apps中,每个不同模块的子应用起不同的名字。startapp后自己移动一下,记得修改一下Appconfig中的name即可。子应用中创建services.py或者如有需要可以创建services模块再细分。所有业务放到services中编写。views一律......