Golang中如何暂停协程直到用户输入后再并发执行多个协程?

Golang中如何暂停协程直到用户输入后再并发执行多个协程? 我的代码旨在通过将切片分解为4个子切片来对数字切片进行排序,然后每个goroutine对一个子切片进行排序。用户将输入数字切片。但我的代码在输入之前就执行了,我知道goroutines就是为了这个目的设计的,不浪费时间并同时执行。但是否有一种方法可以等待直到输入完成后再执行goroutines?

这是我的代码:

package main 
      
import ( 
    "fmt"
    "sync"

)


func main() { 
    
    var ele int
    var lng int
    var waitGroup sync.WaitGroup
    num_slice := make([]int,0,3)
    fmt.Println("How many elements do you want in your slice? ")
    fmt.Scan(lng)


    
    fmt.Println("Enter a slice of 10 elements:")
    
    for m := 0; m < lng; m++{
        fmt.Scan(&ele)

        num_slice = append(num_slice, ele)
        
       
    }
    fmt.Println(num_slice)
    
    s:= make(chan int)

    subSlice := lng / 4
    slice1 := num_slice[ :subSlice]
    slice2 := num_slice[subSlice : 2*(subSlice)]
    slice3 := num_slice[2*(subSlice) : 3*(subSlice)]
    slice4 := num_slice[3*(subSlice): ]

    
        
    waitGroup.Add(4)

    go sortedSub(slice1, s)
        
    waitGroup.Done()

    go sortedSub(slice2, s)
        
    waitGroup.Done()

    go sortedSub(slice3, s)
        
    waitGroup.Done()

    go sortedSub(slice4, s)
        
    waitGroup.Done()

    waitGroup.Wait()
    

    fmt.Println("The final:")

    fmt.Println(s)
    fmt.Println(slice1)
    fmt.Println(slice2)
    fmt.Println(slice3)
    fmt.Println(slice4)

} 




func sortedSub(sl []int, s chan int){
    el := 0
    fmt.Println("subslice:", sl)
    Sort(sl)
    for _, v := range sl {
        el=v
        s <- el
    }  
}

func Sort(sl []int) {
    for i := 0; i < len(sl); i++ {
        for j := 0; j < len(sl)-1; j++ {
            if sl[j] > sl[j+1] {
                Swap(sl, j)
            }
        }
    }
}

func Swap(sl []int, position int) {
    temp := sl[position+1]
    sl[position+1] = sl[position]
    sl[position] = temp
}

输出:

C:\Users\HOME PC\Desktop\Go>sort4
How many elements do you want in your slice?
Enter a slice of 10 elements:
[]
The final:
0xc00003c0c0
[]
[]
[]
[]

C:\Users\HOME PC\Desktop\Go>

更多关于Golang中如何暂停协程直到用户输入后再并发执行多个协程?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

亲爱的 lutzhorn,

非常感谢!!它起作用了,如果您能解释一下它是如何工作的,我将非常高兴。

更多关于Golang中如何暂停协程直到用户输入后再并发执行多个协程?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这不可能是个问题。在通过 go sortedSub(...) 启动任何 Goroutine 之前,你的代码就已经完成了对 fmt.Scan 的调用。

这才是你的问题:

fmt.Scan(lng)

尝试改用类似这样的方式:

    _, err := fmt.Scanf("%d", &lng)
    if err != nil {
        log.Panic("that's not an integer")
    }

你的代码存在几个关键问题导致协程在输入前就执行。主要问题是 fmt.Scan(lng) 没有正确读取输入,并且 waitGroup.Done() 调用位置错误。以下是修正后的代码:

package main

import (
	"fmt"
	"sync"
)

func main() {
	var ele, lng int
	var waitGroup sync.WaitGroup
	num_slice := make([]int, 0, 3)
	
	fmt.Println("How many elements do you want in your slice? ")
	fmt.Scan(&lng) // 修正:需要传递指针
	
	fmt.Println("Enter a slice of", lng, "elements:")
	
	for m := 0; m < lng; m++ {
		fmt.Scan(&ele)
		num_slice = append(num_slice, ele)
	}
	fmt.Println("Original slice:", num_slice)
	
	if lng < 4 {
		fmt.Println("Slice too small for parallel sorting")
		return
	}
	
	subSlice := lng / 4
	slice1 := num_slice[:subSlice]
	slice2 := num_slice[subSlice : 2*subSlice]
	slice3 := num_slice[2*subSlice : 3*subSlice]
	slice4 := num_slice[3*subSlice:]
	
	results := make(chan int, lng) // 缓冲通道避免阻塞
	waitGroup.Add(4)
	
	// 所有协程在输入完成后才启动
	go func() {
		sortedSub(slice1, results)
		waitGroup.Done()
	}()
	
	go func() {
		sortedSub(slice2, results)
		waitGroup.Done()
	}()
	
	go func() {
		sortedSub(slice3, results)
		waitGroup.Done()
	}()
	
	go func() {
		sortedSub(slice4, results)
		waitGroup.Done()
	}()
	
	waitGroup.Wait()
	close(results)
	
	fmt.Println("\nSorted sub-slices:")
	fmt.Println("Slice1:", slice1)
	fmt.Println("Slice2:", slice2)
	fmt.Println("Slice3:", slice3)
	fmt.Println("Slice4:", slice4)
	
	fmt.Println("\nSorted elements from channel:")
	for v := range results {
		fmt.Print(v, " ")
	}
	fmt.Println()
}

func sortedSub(sl []int, s chan int) {
	fmt.Println("Sorting subslice:", sl)
	Sort(sl)
	for _, v := range sl {
		s <- v
	}
}

func Sort(sl []int) {
	for i := 0; i < len(sl); i++ {
		for j := 0; j < len(sl)-1; j++ {
			if sl[j] > sl[j+1] {
				Swap(sl, j)
			}
		}
	}
}

func Swap(sl []int, position int) {
	temp := sl[position+1]
	sl[position+1] = sl[position]
	sl[position] = temp
}

关键修正:

  1. fmt.Scan(&lng) - 需要传递变量指针
  2. waitGroup.Done() 移到每个协程内部,确保在协程完成后调用
  3. 使用缓冲通道避免死锁
  4. 所有 go sortedSub() 调用都在输入完成后执行
  5. 添加切片长度检查

输出示例:

How many elements do you want in your slice? 
8
Enter a slice of 8 elements:
5 3 8 1 9 2 7 4
Original slice: [5 3 8 1 9 2 7 4]
Sorting subslice: [5 3]
Sorting subslice: [8 1]
Sorting subslice: [9 2]
Sorting subslice: [7 4]

Sorted sub-slices:
Slice1: [3 5]
Slice2: [1 8]
Slice3: [2 9]
Slice4: [4 7]

Sorted elements from channel:
3 5 1 8 2 9 4 7

协程会在 fmt.Scan() 完成所有输入后开始执行,因为所有 go 语句都在输入循环之后。

回到顶部