练习题1
要求:
1、启动1个协程,将1~2000个数放进channel里,比如为newChan
2、启动10个协程,从newChan中取出数据n,并计算1+..+n的值,将其存入新的channel中,比如retChan
3、打印retChan的结果,比如ret[1]=1….
package mainimport ("fmt""sync")/*练习题:1、启动1个协程,将1~2000个数放进channel里,比如为newChan2、启动10个协程,从newChan中取出数据n,并计算1+..+n的值,将其存入新的channel中,比如retChan3、打印retChan的结果,比如ret[1]=1....*/var wg sync.WaitGroupfunc writeData(newChan chan int) {// 向里面写入1~2000个数字for i := 1; i <= 2000; i++ {newChan <- i}close(newChan)}func readData(newChan chan int, retChan chan map[int]int) {for {data, ok := <-newChanif !ok {break}ret := 0for i := 0; i < data; i++ {ret += i}retMap := make(map[int]int)retMap[data] = retretChan <- retMapdefer wg.Done()}// close(retChan)}func main() {// 初始channelnewChan := make(chan int, 2000)retChan := make(chan map[int]int, 2000)wg.Add(2000)go writeData(newChan)// 开启8个线程去读写for i := 0; i < 8; i++ {go readData(newChan, retChan)}wg.Wait()close(retChan)for data := range retChan {// fmt.Println(data)for key, value := range data {fmt.Printf("ret[%d]=%d\n", key, value)}}}
练习题2
要求:
1、开启1个协程writeDataToFile,随机生产1000个数字,存放到文件中
2、当writeDataToFile完成1000个数字写入后,让sort协程从中读取1000个数据对其进行排序,并将排序好的数字存入新的文件中
package mainimport ("bufio""fmt""io""math/rand""os""sort""strconv""strings""sync")/*1、开启1个协程writeDataToFile,随机生产1000个数字,存放到文件中2、当writeDataToFile完成1000个数字写入后,让sort协程从中读取1000个数据对其进行排序,并将排序好的数字存入新的文件中*/var wg sync.WaitGroupfunc writeDataToFile(fileChan chan bool) {writeFile, err := os.OpenFile("./random.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)if err != nil {fmt.Println("open file failed, err:", err)return}defer writeFile.Close()for i := 1; i <= 1000; i++ {// 生成随机数randomNum := rand.Int31() % 10000// 将随机数保存到文件中writeFile.WriteString(strconv.Itoa(int(randomNum)) + "\n")}fileChan <- trueclose(fileChan)}func sortData(fileChan chan bool) {for {ret, ok := <-fileChanif !ok {break}if ret {readFile, err := os.Open("./random.txt")if err != nil {fmt.Println("read file failed, err:", err)}defer readFile.Close()newFile, err := os.OpenFile("./newfile.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)if err != nil {fmt.Println("open new file failed, err:", err)return}defer newFile.Close()newReader := bufio.NewReader(readFile)// 逐行读取,将其转换为int,存到slice中var newSlice []intfor {line, err := newReader.ReadString('\n')if err == io.EOF {break}if err != nil {fmt.Println(err)}// fmt.Println()ret, _ := strconv.Atoi(strings.Split(line, "\n")[0])// fmt.Println(ret)// fmt.Printf("%T\n", ret)newSlice = append(newSlice, ret)}// fmt.Println(newSlice)// 对切片进行排序// fmt.Println(len(newSlice))sort.Ints(newSlice)// fmt.Println(len(newSlice))// 将排序好的数据写入新文件for _, v := range newSlice {newFile.WriteString(strconv.Itoa(v) + "\n")}defer wg.Done()// close(exitChan)}}}func main() {// 定义一个channel,用来记录文件已经写完fileChan := make(chan bool, 1)// exitChan := make(chan bool, 1)wg.Add(1)go writeDataToFile(fileChan)// go sortData(fileChan, exitChan)go sortData(fileChan)// for {// _, ok := <-exitChan// if !ok {// break// }// }wg.Wait()}
扩展:
1、开启10个协程writeDataToFile,随机生产1000个数字,存放到10文件中
2、当writeDataToFile完成10个文件1000个数字写入后,让sort协程从10个文件中读取1000个数据对其进行排序,并将排序好的数字存入新的10的文件中
练习题3
使用goroutine和channel实现一个计算int64随机数各位数和的程序。
1、开启一个goroutine循环生成int64类型的随机数,发送到jobChan
2、开启24个goroutine从jobChan中取出随机数计算各位数的和,将结果发送到resultChan
3、主goroutine从resultChan取出结果并打印到终端输出
package mainimport ("fmt""math/rand""sync""time")/*使用goroutine和channel实现一个计算int64随机数各位数和的程序。1、开启一个goroutine循环生成int64类型的随机数,发送到jobChan2、开启24个goroutine从jobChan中取出随机数计算各位数的和,将结果发送到resultChan3、主goroutine从resultChan取出结果并打印到终端输出*/type job struct {value int64}type result struct {job *jobsum int64}var wg sync.WaitGroupfunc insertData(ch1 chan<- *job) {defer wg.Done()// 循环写for {// 生成随机数num := rand.Int63()// 实例化jobnumJob := &job{value: num,}ch1 <- numJobtime.Sleep(time.Millisecond * 500)}}func sumData(ch1 <-chan *job, retChan chan<- *result) {defer wg.Done()for {// 循环从ch1读数据num := <-ch1sum := int64(0)// 计算位数之和n := num.valuefor n > 0 {sum += n % 10n = n / 10}// 实例化resultnewResult := &result{job: num,sum: sum,}retChan <- newResult}}func main() {inChan := make(chan *job, 100)retChan := make(chan *result, 100)wg.Add(1)go insertData(inChan)for i := 1; i <= 24; i++ {wg.Add(1)go sumData(inChan, retChan)}// 打印结果for ret := range retChan {fmt.Printf("Job: [%d] Sum: [%d]\n", ret.job.value, ret.sum)}wg.Wait()}
