goroutine 或多线程在 golang 中不起作用
goroutine or multithreading is not working in golang
我试图在 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 个线程并想用不同的线程处理不同的值。如果您将看到上面的示例,它会打印 "bye" 4 次。
我想要使用 5 个线程进行如下输出,
good0bye0good1bye1good2bye2....等....
知道我怎样才能做到这一点吗?
首先,您需要在主函数中阻塞,直到所有其他 goroutines return。您程序中的互斥量不会阻塞 任何东西,并且由于它们在每个循环中都被重新初始化,所以它们甚至不会在自己的 goroutine 中阻塞。如果您不是 return 从函数中退出,则不能延迟解锁,您需要在循环的每次迭代中显式解锁。您没有使用数组中的任何值(尽管您应该使用切片代替),因此我们可以完全放弃它。你也不需要 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。
我试图在 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 个线程并想用不同的线程处理不同的值。如果您将看到上面的示例,它会打印 "bye" 4 次。
我想要使用 5 个线程进行如下输出,
good0bye0good1bye1good2bye2....等....
知道我怎样才能做到这一点吗?
首先,您需要在主函数中阻塞,直到所有其他 goroutines return。您程序中的互斥量不会阻塞 任何东西,并且由于它们在每个循环中都被重新初始化,所以它们甚至不会在自己的 goroutine 中阻塞。如果您不是 return 从函数中退出,则不能延迟解锁,您需要在循环的每次迭代中显式解锁。您没有使用数组中的任何值(尽管您应该使用切片代替),因此我们可以完全放弃它。你也不需要 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。