所以我有一个这样的文件:
NAME : a280
COMMENT : drilling problem (Ludwig)
TYPE : TSP
DIMENSION: 280
EDGE_WEIGHT_TYPE : EUC_2D
NODE_COORD_SECTION
1 288 149
2 288 129
3 270 133
4 256 141
5 256 157
6 246 157
7 236 169
8 228 169
9 228 161
10 220 169
11 212 169
12 204 169
13 196 169
14 188 169
15 196 161
依旧......
这些数字是城市解决TSP的线索。我想在Golang写这个。现在这些实例可能像200个城市,甚至是40,000个城市。我想获得最好的解决方案,所以我认为我应该同时处理这个文件。我有以下代码:
package main
import (
"bufio"
"fmt"
"os"
"regexp"
"strings"
)
func getCords(queue chan string) {
cords := regexp.MustCompile(`\s*\d+\s+\d+\s+\d+`)
for line := range queue {
if cords.MatchString(line) {
fmt.Println(line)
}
}
}
func readFile(fileName string) {
cords := make(chan string)
file := strings.NewReader(fileName)
go func() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
cords <- scanner.Text()
}
close(cords)
}()
}
// Menu - main program menu
func Menu() {
reader := bufio.NewReader(os.Stdin)
fmt.Println("================== Projektowanie efektywnych algorytmów ==================")
fmt.Println("================== Zadanie nr 1 - Algorytm xyz ==================")
// Wczytywanie pliku z danymi
// Format: Lp. X Y
fmt.Printf("\nPodaj nazwę pliku: ")
fileName, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
readFile(fileName)
}
func main() {
Menu()
}
在函数getCords
中我需要使用regex,因为文件往往在开头就有信息部分。
问题始于readFile()
。我启动了一个goroutine,它逐行扫描文件并获取通道的所有行。当然,执行只会启动它并进一步发展。现在的问题是,在go func()
调用之后,我将不得不尝试从频道中读取。我在SO和互联网上找到的解决方案如下:
func readFile(fileName string) {
cords := make(chan string)
file := strings.NewReader(fileName)
go func() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
cords <- scanner.Text()
}
close(cords)
}()
for i := 0; i < 100; i++ {
go getCords(cords)
}
}
因此,首次执行getCords甚至可能什么都不做,因为goroutine无法设法快速获得通道。下一次迭代可能会完成这项工作,但问题是我必须编写一些数字,例如本例中的100
,并且它可能太高,因此通道将在10次迭代中关闭,之后它会&只是浪费时间或者它可能太低,然后我就不会得到所有的结果。
你怎么解决这样的问题,伙计们?有最佳方式,还是我必须坚持使用waitGroups
?
答案 0 :(得分:1)
我认为是的,使用sync.WaitGroup
确保所有goroutine完成工作会更好。一种可能的解决方案:
func getCords(queue Chas string, wg sync.WaitGroup) {
defer wg.Done()
// your code
}
func readFile(fileName string) {
cords := make(chan string)
file := strings.NewReader(fileName)
go func() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
cords <- scanner.Text()
}
close(cords)
}()
wg := sync.WaitGroup{}
for i := 0; i < 100; i++ {
wg.Add(1)
go getCords(cords, wg)
}
wg.Wait()
}