donglu5728 2014-12-08 20:23
浏览 19

使用并发的Golang装配线

New to Go. I'm attempting to code an "assembly line" where multiple functions act like workers and pass some data structure to each other down the line, each doing something to the data structure.

type orderStruct struct {
    orderNum,capacity int
    orderCode uint64
    box [9]int
}


func position0(in chan orderStruct){

    order := <-in

    if((order.orderCode<<63)>>63 == 1){
        order.box[order.capacity] = 1
        order.capacity += 1
    }

    fmt.Println("  filling box {", order.orderNum, order.orderCode, order.box, order.capacity, "} at position 0")
}

func startOrder(in chan orderStruct){

    order := <-in

    fmt.Printf("
Start an empty box for customer order number %d , request number %d
", order.orderNum, order.orderCode)
    fmt.Println("  starting box {", order.orderNum, order.orderCode, order.box, order.capacity, "}")

    d := make(chan orderStruct,1)
    go position0(d)
    d <- order
}

func main() {

    var orders [10]orderStruct
    numOrders := len(os.Args)-1
    var x int

    for i := 0; i < numOrders; i++{
        x, _ = strconv.Atoi(os.Args[i+1])
        orders[i].orderCode = uint64(x)
        orders[i].orderNum = i+1
        orders[i].capacity = 0
        for j := 0; j < 9; j++{
            orders[i].box[j] = 0
        }
        c := make(chan orderStruct)
        go startOrder(c)
        c <- orders[i]
    }
}

So basically the issue I'm having is that the print statements in startOrder() execute fine, but when I try to pass the struct to position0(), nothing is printed. Am I misunderstanding how channels work?

  • 写回答

2条回答 默认 最新

  • dongshengheng1013 2014-12-08 22:36
    关注

    I've attempted to re-write what you've written to work properly. You can run it on the playground

    The main differences are

    • only two go routines are started - these act as the two workers on the production line - one taking orders and the other filling boxes
    • use of sync.WaitGroup to find out when they end
    • use of for x := range channel
    • use of close(c) to signal end of channel
    • you could start multiple copies of each worker and the code would still work fine (repeat the wg.Add(1); go startOrders(c, wg) code)

    Here is the code

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    type orderStruct struct {
        orderNum, capacity int
        orderCode          uint64
        box                [9]int
    }
    
    func position0s(in chan orderStruct, wg *sync.WaitGroup) {
        defer wg.Done()
        for order := range in {
            if (order.orderCode<<63)>>63 == 1 {
                order.box[order.capacity] = 1
                order.capacity += 1
            }
            fmt.Println("  filling box {", order.orderNum, order.orderCode, order.box, order.capacity, "} at position 0")
        }
    }
    
    func startOrders(in chan orderStruct, wg *sync.WaitGroup) {
        defer wg.Done()
        d := make(chan orderStruct)
        wg.Add(1)
        go position0s(d, wg)
    
        for order := range in {
            fmt.Printf("
    Start an empty box for customer order number %d , request number %d
    ", order.orderNum, order.orderCode)
            fmt.Println("  starting box {", order.orderNum, order.orderCode, order.box, order.capacity, "}")
            d <- order
        }
        close(d)
    }
    
    func main() {
        var orders [10]orderStruct
        numOrders := 4
        var x int = 10
        wg := new(sync.WaitGroup)
        c := make(chan orderStruct)
        wg.Add(1)
        go startOrders(c, wg)
        for i := 0; i < numOrders; i++ {
            orders[i].orderCode = uint64(x)
            orders[i].orderNum = i + 1
            orders[i].capacity = 0
            for j := 0; j < 9; j++ {
                orders[i].box[j] = 0
            }
            c <- orders[i]
        }
        close(c)
        wg.Wait()
    }
    
    评论

报告相同问题?