结果与并发功能不一致?

时间:2018-09-03 23:12:20

标签: go concurrency

我正在尝试同时处理文件中的行,但是由于某种原因,我似乎得到不一致的结果。我的代码的简化版本如下:

@FindBy(xpath = "./menu_locator")
public class SiteMenu extends HtmlElement {
    @FindBy(xpath = "./generic_item_locator")
    List<HtmlElement> items

    public clickOn(String navigatorName) {
        for (HtmlElement item: items) {
            if (item.getText() == "navigatorName") {
                item.click();
            }
        }
        throw new ElementNotFoundException("Navigator item not found")
    }
}

var wg sync.WaitGroup semaphore := make(chan struct{}, 2) lengths:= []int{} for _, file := range(args[1:]){ // Open the file and start reading it reader, err := os.Open(file) if err != nil { fmt.Println("Problem reading input file:", file) fmt.Println("Error:", err) os.Exit(0) } scanner := bufio.NewScanner(reader) // Start streaming lines for scanner.Scan() { wg.Add(1) text := scanner.Text() semaphore <- struct{}{} go func(line string) { length := getInformation(line) lengths = append(lengths, length) <-semaphore wg.Done() }(text) } } wg.Wait() sort.Ints(lengths) fmt.Println("Lengths:", lengths) 函数只是返回行的长度。然后,我将那条线添加到数组中。我遇到的问题是,当我对同一个文件多次运行时,数组中的项目数不同。我假设自从使用getInformation以来,所有行都将被处理,因此waitGroup的内容将是相同的,但是事实并非如此。有人可以在这里看到我在做什么错吗?

1 个答案:

答案 0 :(得分:2)

lengths = append(lengths, length)正在同时执行。这是不安全的,并且会引起问题,例如缺少切片中的条目。您可以通过将append调用包装在互斥体中来解决此问题,或者让gorountines将结果发布到一个通道中,并在一个地方将其收集到一个切片中。