【问题标题】:goroutine or multithreading is not working in golanggoroutine 或多线程在 golang 中不起作用
【发布时间】:2016-09-09 18:28:59
【问题描述】:

我试图在 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) 

    }



}

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

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

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

good0bye0good1bye1good2bye2....等等....

知道如何实现吗?

【问题讨论】:

  • 您的主要功能没有任何障碍。你的程序在你看到所有输出之前就退出了。
  • @JimB 感谢您的回复。但它正在写入文件并正常工作。
  • 除了 main 中没有阻塞(你需要先修复)之外,互斥锁没有锁定 任何东西,因为它们不在 goroutines 之间共享,另外还有一个为每个循环初始化了单独的互斥锁,因此它甚至不会在 goroutine 中阻塞。当您不返回时,您调用 defer 来解锁锁。在行为良好的程序中,您永远不需要调用 runtime.GoSched
  • @JimB 再次感谢您的宝贵意见。明白你的意思。但是您能否更正我的程序,以便我可以创建 5 个线程,每个线程将打印不同的值。这对我会有很大帮助。我是从我身边做的,但无法理解。请帮帮我。

标签: multithreading go concurrency goroutine


【解决方案1】:

首先,您需要阻塞您的 main 函数,直到所有其他 goroutine 返回。程序中的互斥锁不会阻塞任何东西,而且由于它们在每个循环中都会重新初始化,因此它们甚至不会在自己的 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。

【讨论】:

  • 非常感谢您的合作..我会努力实现它。我希望它正在创建 5 个线程,并且每个线程都打印不同的值。顺便说一句,这是在 GoLang 中实现多线程的正确方法,还是有其他简单的方法可以做到这一点?
  • Go 不公开操作系统线程,所以是的,您使用 goroutines 进行并发。
  • 明白你的意思。但是我仍然无法在这里实现并行性。在上面的示例中,我正在一一锁定和处理数据。我想并行处理所有线程。知道我该怎么做吗?例如 - 如果有集合并想从服务或数据库中获取数据,我该怎么做?
  • @user2768132:我不明白你的意思。每个 goroutine 并发运行,可能在多个线程上并行调度,锁定仅围绕共享文件写入。查询数据库是完全不相关的。
  • 感谢您的回复。实际上,我正在尝试在写入文件之前点击服务 url。在点击 URL 后,我正在将响应写入文件。如果我看到当前示例,我认为它由于锁定而没有并行运行。首先它是锁定并写入文件。直到那时所有其他线程都在等待。我对么?请指导我。
猜你喜欢
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 2020-11-01
  • 1970-01-01
  • 2018-09-11
  • 1970-01-01
相关资源
最近更新 更多