• 练习题1


    一 控制单个goroutine执行5次就结束

    package main
    
    // 编写一个程序,控制单个goroutine执行5次就结束
    import (
    	"context"
    	"fmt"
    	"sync"
    )
    
    // 控制goroutine 执行5次结束
    func main() {
    	// 定义一个运行次数变量
    	runCount := 0
    	//定义一个waitgroup,等待goroutine执行完成
    	var wg sync.WaitGroup
    	// 初始化context
    	parent := context.Background()
    	// 传入初始化的ctx,返回ctx和cancle函数
    	ctx, cancle := context.WithCancel(parent)
    	wg.Add(1) // 增加一个任务
    	go func() {
    		for {
    			select {
    			case <-ctx.Done():
    				fmt.Println("任务结束")
    				return
    			default:
    				fmt.Printf("任务执行了%d次\n", runCount)
    				runCount++
    			}
    			// 执行了5次,使用ctx的取消函数将任务取消
    			if runCount >= 5 {
    				cancle()
    				wg.Done() // goroutine执行完成
    			}
    
    		}
    	}()
    
    	wg.Wait() //等待所有任务完成
    
    }
    
    

    二 100个老太太抢10个鸡蛋

    package main
    
    import (
    	"fmt"
    	"sync"
    )
    
    // 100个老太太抢10个鸡蛋
    func main() {
    	// 初始化一个waitgroup
    	var wg sync.WaitGroup
    	// 初始化一个可以放10个鸡蛋的篮子
    	var c=make(chan string,10)
    	// 把鸡蛋放入篮子中
    	for i:=0;i<10;i++{
    		c<-fmt.Sprintf("鸡蛋%d号",i)
    	}
    
    	// 启动100个gorouting,模拟100个老太太抢鸡蛋
    	for i := 0; i <100 ; i++ {
    		//开启抢鸡蛋的任务
    		wg.Add(1) // 增加一次wg
    		go func(num int) {
    			//模拟延迟
    			//time.Sleep(1*time.Second)
    			select {
    			case e:=<-c: // 从c中取出一个鸡蛋
    				fmt.Printf("第%d个老太太,抢到了:%s\n",num,e)
    			default:
    				// 什么都不处理,最后会继续执行wg.Done()
    				fmt.Printf("第%d个老太太抢破头,也没有抢到鸡蛋\n",num)
    			}
    			wg.Done() // 抢完通知wg结束
    		}(i)
    
    
    	}
    	wg.Wait()
    
    
    }
    
    

    三 生产者消费者场景

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    //包子铺老板生产包子,消费者吃包子
    // 生产者消费者场景(1 生产者消费者数量均等;2 生产者多,消费者少;3 生产者少,消费者多)
    
    // 定义一个全局channel,放包子的盘子
    var c=make(chan string,10)
    
    // 老板包包子(生产者)
    func producer(index int)  {
    	fmt.Printf("蒸了第【%d】号包子,放到盘子中\n",index)
    	c<-fmt.Sprintf("包子%d号",index)
    }
    // 顾客吃包子(消费者)
    func consumer(index int)  {
    	//bz:=<-c
    	select {
    	case bz:=<-c:
    		fmt.Printf("第%d号顾客,吃了:【%s】\n",index,bz)
    	default:
    		fmt.Printf("第%d号顾客,没吃到包子\n",index)
    
    
    	}
    
    
    }
    func main() {
    	//1 -------- 10个人生产包子,10个人吃包子
    	// 10个人生产
    	//for i := 0; i < 10; i++ {
    	//	go producer(i)
    	//}
    	//// 10个人吃
    	//for i := 0; i < 10; i++ {
    	//	go consumer(i)
    	//}
    	//time.Sleep(5*time.Second) // 不使用wg控制
    
    
    	//2 -------- 10个人生产包子,100个人吃包子
    	//10个人生产
    	//for i := 0; i < 10; i++ {
    	//	go producer(i)
    	//}
    	//// 100个人吃
    	//for i := 0; i < 100; i++ {
    	//	go consumer(i)
    	//}
    	//time.Sleep(5*time.Second) // 不使用wg控制
    
    
    	//3 100个人生产,10个人吃包子
    	// 100个人生产
    	for i := 0; i < 100; i++ {
    		go producer(i)
    	}
    	// 10个人吃
    	for i := 0; i < 10; i++ {
    		go consumer(i)
    	}
    	time.Sleep(5*time.Second) // 不使用wg控制
    
    
    }
    
    

    四 练习题

    题目:某工厂有A、B、C三辆厨房工程车,A车上能清洗材料,B车
    上能加工材料, C车上能装载材料;三辆工程车能边行驶边清洗/加
    工/装载材料,每辆车上有3个工人;最初的原始材料有D1、D2、
    D3三种材料,每种材料的清洗耗时比例为6:3:3 ,每种材料的加工/
    装载耗时皆为1:1:1 ,每种材料的数量一致;材料的处理顺序为, 清
    洗->加工->装载;车辆之间材料进行交互,需要保持比较近的相对
    距离
    要求:这三辆车需要将处理完的原材料,尽快送达商家手里。请问
    如何分配比较好?
    
    条件
    //1 ABC三辆工程车
    //2 A清洗  B加工   C装载
    
    //3 三辆工程车边行驶,边 清洗/加工/装载材料,每辆车有三个工人
    //4 有原始材料:D1,D2,D3,每种材料清洗耗时:6:3:3
    //5 每种材料加工,装载耗时:1:1:1,材料数量一致
    
    约束
    //1 材料处理顺序为:清洗---》加工---》装载
    //2 车辆之间材料进行交互,要保持相对近的距离
    
    要求
    // 处理完的原材料,尽快送到商家手中
    
    
    goroutine
    //1 三辆工程车分别为3个goroutine
    //2 三辆车,3个func,分别执行不同功能--》A车:funcA;B车:funcB;C车:funcC
    //3 每个func内部有3个子goroutine,代表3个工人
    //4 funcB和funcC步骤的材料处理时间相等,因此每个工人负责对应的材料堆即可
    //5 funcA材料耗时不一,对材料重新整合,将每种材料3等分,每个工人分到三分之一,进行加工
    
    channal
    // 材料的传输:funcA==》funcB==》funcC
    // 最后由c运送给商家
    
    注意
    // 三辆工程车一起开出
    
    package main
    
    import (
    	"fmt"
    	"sync"
    )
    
    var (
    	wg       sync.WaitGroup             // 管理每个车中3个工人的完成
    	globalWg sync.WaitGroup             // 管理3两车的完成
    	ch       = make(chan []string, 3) // 用来在三个车(goroutine)之间传递材料
    )
    
    // 工程车A:清洗材料
    func funcA(elements []string) { // 传入材料
    	// 把传入的材料进行切分
    	for index,element:=range elements{
    		wg.Add(1)
    		go func(element string,index int) {
    			elements[index]=clean(element)
    			wg.Done()
    		}(element,index)
    	}
    	wg.Wait()
    	ch<-elements
    	fmt.Println(len(ch))
    	globalWg.Done()
    }
    
    // 工程车B:加工材料
    func funcB() {
    	// 接收材料
    	var elements =[]string{}
    	for  {
    		select {
    		case elements =<-ch:  // 接收到某种材料,就结束死循环,开始处理,接收不到,继续等待接收
    			fmt.Println("收到了")
    			break
    		default:
    			fmt.Println("没收到")
    			fmt.Println(len(ch))
    			continue
    		}
    	}
    	// 分配3个工人开始加工材料
    	for index,element:=range elements{
    		wg.Add(1)
    		go func(element string,index int) {
    			elements[index]=cure(element)
    			wg.Done()
    		}(element,index)
    	}
    	wg.Wait()
    	ch<-elements
    	globalWg.Done()
    
    }
    
    // 工程车C:运载材料
    func funcC() {
    	// 接收材料
    	var elements =[]string{}
    	for  {
    		select {
    		case elements =<-ch:  // 接收到某种材料,就结束死循环,开始处理,接收不到,继续等待接收
    			break
    		default:
    			continue
    		}
    	}
    	// 分配3个工人开始运输材料
    	for index,element:=range elements{
    		wg.Add(1)
    		go func(element string,index int) {
    			elements[index]=carry(element)
    			wg.Done()
    		}(element,index)
    	}
    	wg.Wait()
    	globalWg.Done()
    
    }
    func main() {
    
    	var elements = []string{"材料1", "材料2", "材料3"}
    	globalWg.Add(1)
    	go funcA(elements)
    	globalWg.Add(1)
    	go funcB()
    	globalWg.Add(1)
    	go funcC()
    	globalWg.Wait()
    
    	//elements=<-ch
    	fmt.Println(elements)
    
    }
    
    // 清洗功能
    func clean(element string) string {
    	return fmt.Sprintf("材料【%s】被清洗了---》", element)
    }
    
    // 加工功能
    func cure(element string) string {
    	return fmt.Sprintf("材料【%s】被加工了---》", element)
    }
    
    // 运输功能呢
    func carry(element string) string {
    	return fmt.Sprintf("材料【%s】被运输了---》", element)
    }
    
    
  • 相关阅读:
    Bzoj 1010: [HNOI2008]玩具装箱toy(斜率优化)
    Cogs 376. [IOI2002]任务安排(后效性DP)
    Bzoj 1911: [Apio2010]特别行动队(斜率优化)
    Poj 2018 Best Cow Fences(分数规划+DP&&斜率优化)
    Bzoj 1212: [HNOI2004]L语言(AC自动机+DP)
    ZOJ 3228 Searching the String(AC自动机)
    Bzoj 3172: [Tjoi2013]单词(fail树)
    Hdu 3065 病毒侵袭持续中(AC自动机)
    Hdu 2896 病毒侵袭(AC自动机)
    Bzoj 2599: [IOI2011]Race(点分治)
  • 原文地址:https://www.cnblogs.com/liuqingzheng/p/16028319.html
Copyright © 2020-2023  润新知