MIT 6.824学习笔记(1)——go routine 和 go channel的协作递归

在完成单个任务下发到worker,然后worker进行处理完成的阶段后。

此时需要coordinator进行任务调度处理,以此让所有空闲的worker进行并行工作

要想完成lab1此阶段的任务,需要熟悉以下Go语言的知识

  • go routine
  • go channel

下面以一个简单的例子进行学习演示

该程序完成一个递归爬虫爬取页面的任务(此处进行简化处理)。一个url页面下面可能会有很多个新的url,该程序需要爬取到所有的url后,才进行返回。

采用深度优先的方式进行爬取,由于子程序采用go routine的方式,所以为了防止共享数据的访问冲突。下文采用同步锁或者go channel的方式分别实现。

  • 使用锁的方式实现
package main

import (
	"fmt"
	"sync"
)

type Fetcher struct {}

func (f Fetcher) ParseUrl(url string) (urls []string, err error) {
	urls = append(urls, url)
	err = nil
	return
}

type fetchState struct{
	mu sync.Mutex
	fetched map[string]bool
}

// 使用锁实现一个递归解析url的函数
func recursion(url string, fetcher Fetcher ,f *fetchState) {
	f.mu.Lock()
	already := f.fetched[url]
	f.fetched[url] = true
	f.mu.Unlock()

	if already {
		return
	}
	fmt.Println(url)
	urls, _ := fetcher.ParseUrl(url)

	var wg sync.WaitGroup
	for _, v := range urls {
		wg.Add(1)
		go func(u string) {
			defer wg.Done()
			recursion(u, fetcher, f)
		}(v)
	}
	wg.Wait()
}

func main() {
	recursion("test", Fetcher{}, &fetchState{
		fetched: make(map[string]bool, 0)
	})
}
  • 使用go channel的方式实现
package main

import (
	"fmt"
	"sync"
)

type Fetcher struct {}

func (f Fetcher) ParseUrl(url string) (urls []string, err error) {
	urls = append(urls, url)
	err = nil
	return
}

type fetchState struct{
	mu sync.Mutex
	fetched map[string]bool
}

// 使用chan实现一个递归解析url的函数
func recursion2(url string, fetcher Fetcher) {
	ch := make(chan []string, 0)
	// ch <- []string{url} 此处会引发死锁
	go func() {
		ch <- []string{url}
	}()
	master(ch, fetcher)
}

func master(ch chan []string, fetcher Fetcher) {
	fetched := make(map[string]bool, 0)
	i := 0
	for urls := range ch {
		for _, v := range urls {
			if fetched[v] == false {
				go worker(ch, v, fetcher)
				fetched[v] = true
				i += 1
			}
		}
		i -= 1
		if i == 0 {
			break
		}
	}
}

func worker(ch chan []string, url string, fetcher Fetcher) {
	urls, _ := fetcher.ParseUrl(url)
	// 简单处理,此处默认成功
	ch <- urls
}

func main() {
	recursion2("hanbo", Fetcher{})
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lingwu_hb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值