goroutine或多线程在golang中不起作用

时间:2016-09-09 18:28:59

标签: multithreading go concurrency goroutine

我试图在golang中实现多线程。我能够实现go例程但它没有按预期工作。以下是我准备的示例程序,

func test(s string, fo *os.File) {
    var s1 [105]int
    count :=0
    for x :=1000; x<1101;x++ {
    s1[count] = x;
        count++
    }

    //fmt.Println(s1[0])
    for i := range s1 {
        runtime.Gosched() 
        sd := s + strconv.Itoa(i)
        var fileMutex sync.Mutex
        fileMutex.Lock()
        fmt.Fprintf(fo,sd)
        defer fileMutex.Unlock()
    }
}

func main() {
    fo,err :=os.Create("D:/Output.txt")
    if err != nil {
        panic(err)
    }
    for i := 0; i < 4; i++ {
        go test("bye",fo) 

    }



}

OUTPUT - good0bye0bye0bye0bye0good1bye1bye1bye1bye1good2bye2bye2bye2bye2 ....等 上面的程序将创建一个文件并在文件中写“Hello”和“bye”。

我的问题是我正在尝试创建5个线程,并希望使用不同的线程处理不同的值。如果您将看到上面的示例,它将打印“再见”4次。

我希望输出如下,使用5个线程,

good0bye0good1bye1good2bye2 ....等....

任何想法我怎么能实现这个目标?

1 个答案:

答案 0 :(得分:3)

首先,您需要阻止主函数,直到所有其他goroutines返回。程序中的互斥锁不会阻塞任何,并且由于它们在每个循环中重新初始化,因此它们甚至不会在自己的goroutine中阻塞。如果您没有从函数返回,则无法推迟解锁,您需要在循环的每次迭代中显式解锁。您没有使用数组中的任何值(尽管您应该使用切片),因此我们可以完全放弃它。在一个表现良好的程序中你也不需要runtime.GoSched,它在这里什么都不做。

将运行至完成的等效程序如下所示:

var wg sync.WaitGroup

var fileMutex sync.Mutex

func test(s string, fo *os.File) {
    defer wg.Done()
    for i := 0; i < 105; i++ {
        fileMutex.Lock()
        fmt.Fprintf(fo, "%s%d", s, i)
        fileMutex.Unlock()
    }
}

func main() {
    fo, err := os.Create("D:/output.txt")
    if err != nil {
        log.Fatal(err)
    }
    for i := 0; i < 4; i++ {
        wg.Add(1)
        go test("bye", fo)

    }
    wg.Wait()
}

最后,没有理由尝试将串行值写入多个goroutine的单个文件中,这样做效率较低。如果您想要在整个文件中订购的值,则无论如何都需要使用单个goroutine。