一道题给大家做一下。。。

zzxap 2020-10-29 09:09:13
//用程序实现一个函数,原型为:func printNumber(N int)
//内部创建三个线程A、B、C,三个线程交替输出1到N之间的数字,
//A线程输出1、4、7…,B线程2、5、8…,C线程输出3、6、9…,
//最终结果为:1、2、3、4、5...N

...全文
294 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
Nihility/ 2021-02-19
  • 打赏
  • 举报
回复
引用 2 楼 qybao 的回复:
这道题确实没啥意思,用channel 阻塞控制一下协程就可以了,谈不上什么锁(当然,用锁控制也可以)
package main

import "fmt"

func printNumber(N int) {
	chs := []chan int {
		make(chan int), //use to block A go func
		make(chan int), //use to block B go func
		make(chan int), //use to block C go func
		make(chan int), //use to block main
	}
	go func(ch []chan int, from int, to int, finish int) { //A print data from chs[0] and send next to chs[1] to awake B
		for ;; {
			select {
			case data := <-ch[from]:
				fmt.Printf("A:%d ", data); //use A prefix to check which go func prints the data
				if data == N {
					ch[finish] <- 0; //if come to the end of data, send signal to chs[3] to awake main
				} else {
					ch[to] <- data + 1;
				}
			}
		}
	}(chs, 0, 1, 3);

	go func(ch []chan int, from int, to int, finish int) { //B print data from chs[1] and send next to chs[2] to awake C
		for ;; {
			select {
			case data := <-ch[from]:
				fmt.Printf("B:%d ", data);
				if data == N {
					ch[finish] <- 0; //if come to the end of data, send signal to chs[3] to awake main
				} else {
					ch[to] <- data + 1;
				}
			}
		}
	}(chs, 1, 2, 3);

	go func(ch []chan int, from int, to int, finish int) { //A print data from chs[2] and send next to chs[0] to awake A
		for ;; {
			select {
			case data := <-ch[from]:
				fmt.Printf("C:%d ", data);
				if data == N {
					ch[finish] <- 0; //if come to the end of data, send signal to chs[3] to awake main
				} else {
					ch[to] <- data + 1;
				}
			}
		}
	}(chs, 2, 0, 3);

	chs[0] <- 1; //awake A go fun
	<-chs[3]; //block main until all go func finish
	for _, ch := range chs { //close all channel
		close(ch)
	}
	fmt.Println()
}

func main () {
	var N int;
	fmt.Printf("please input a number: ");
	fmt.Scanf("%d", &N);
	printNumber(N);
}
新年好,答主!请问一下,这段代码,go run ./main.go 运行第二遍会进入死循环输出,是哪里有问题?
qybao 2020-10-30
  • 打赏
  • 举报
回复
这道题确实没啥意思,用channel 阻塞控制一下协程就可以了,谈不上什么锁(当然,用锁控制也可以)

package main

import "fmt"

func printNumber(N int) {
chs := []chan int {
make(chan int), //use to block A go func
make(chan int), //use to block B go func
make(chan int), //use to block C go func
make(chan int), //use to block main
}
go func(ch []chan int, from int, to int, finish int) { //A print data from chs[0] and send next to chs[1] to awake B
for ;; {
select {
case data := <-ch[from]:
fmt.Printf("A:%d ", data); //use A prefix to check which go func prints the data
if data == N {
ch[finish] <- 0; //if come to the end of data, send signal to chs[3] to awake main
} else {
ch[to] <- data + 1;
}
}
}
}(chs, 0, 1, 3);

go func(ch []chan int, from int, to int, finish int) { //B print data from chs[1] and send next to chs[2] to awake C
for ;; {
select {
case data := <-ch[from]:
fmt.Printf("B:%d ", data);
if data == N {
ch[finish] <- 0; //if come to the end of data, send signal to chs[3] to awake main
} else {
ch[to] <- data + 1;
}
}
}
}(chs, 1, 2, 3);

go func(ch []chan int, from int, to int, finish int) { //A print data from chs[2] and send next to chs[0] to awake A
for ;; {
select {
case data := <-ch[from]:
fmt.Printf("C:%d ", data);
if data == N {
ch[finish] <- 0; //if come to the end of data, send signal to chs[3] to awake main
} else {
ch[to] <- data + 1;
}
}
}
}(chs, 2, 0, 3);

chs[0] <- 1; //awake A go fun
<-chs[3]; //block main until all go func finish
for _, ch := range chs { //close all channel
close(ch)
}
fmt.Println()
}

func main () {
var N int;
fmt.Printf("please input a number: ");
fmt.Scanf("%d", &N);
printNumber(N);
}

ying1234 2020-10-29
  • 打赏
  • 举报
回复
没什么意思的题目,想干嘛?想3个线程同步交替输出?那为什么要用3个线程? 如果是并发输出,那么大概思路如下 定义一个总的 var arrresult []int A协程: 初始值=1,每次循环加3,大于N退出,arrresult =append(arrresult,产生的值)(加锁一下) B协程: 初始值=2,每次循环加3,大于N退出,arrresult =append(arrresult,产生的值)(加锁一下) C协程: 初始值=3,每次循环加3,大于N退出,arrresult =append(arrresult,产生的值)(加锁一下) 最后对arrresult 排序输出。

2,190

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • Freeman Z
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧