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

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)  
 
    } 
 
 
 
} 

输出 - good0bye0bye0bye0bye0good1bye1bye1bye1bye1good2bye2bye2bye2bye2 ....等等。 上面的程序会创建一个文件,并在文件中写入“Hello”和“bye”。

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

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

good0bye0good1bye1good2bye2....等....

知道我怎样才能做到这一点吗?

请您参考如下方法:

首先,您需要在主函数中阻塞,直到所有其他 goroutine 返回。您程序中的互斥量不会阻塞任何东西,并且由于它们在每个循环中都被重新初始化,所以它们甚至不会阻塞在它们自己的 goroutine 中。如果您不从函数返回,则不能延迟解锁,您需要在循环的每次迭代中显式解锁。您没有使用数组中的任何值(尽管您应该使用 slice 代替),因此我们可以完全放弃它。您也不需要在行为良好的程序中使用 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。


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!