2014-12-08 2 views
0

New to Go. 여러 함수가 작업자처럼 작동하고 데이터 구조를 서로 줄이면서 서로 데이터 구조를 전달하는 "어셈블리 선"을 코딩하려고합니다.Golang의 어셈블리 라인 동시성 사용

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("\nStart an empty box for customer order number %d , request number %d\n", 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] 
    } 
} 

그래서 기본적으로 나는 데 문제가 startOrder에서 인쇄 문() 잘 실행한다는 것입니다,하지만 난) (POSITION0하는 구조체를 통과 할 때, 아무것도 인쇄되지 않습니다. 채널이 어떻게 작동하는지 오해하고 있습니까?

+0

http://blog.golang.org/pipelines를 읽는 것이 좋습니다. 문제가되는 디자인이 두 가지 이상 있습니다. – Momer

+0

(무작위 관찰, 실제 질문의 측면에서 : 나는 한 번 파이프 라인을 병렬로 만들었지 만 명시 적으로 동시 발생하는 부분은 몇 가지''io.Copy (w, r)' '였습니다. 해당 모델에 적합하지만 코드의 상당 부분에서 동시성을 숨길 수 있다면 도움이 될 것입니다.) – twotwotwo

답변

1

필자가 작성한 내용을 올바르게 작성하려고 시도했습니다. 당신은 run it on the playground

의 주요 차이점은 두 이동 루틴이 시작되는

  • 입니다 수 - 일 개 촬영 주문과 다른 충전 상자 sync.WaitGroup
  • 사용에 -하여 생산 라인에 두 노동자 이러한 행위 그들이
  • 사용 x의 끝 때 알아 : = 범위 채널
  • 당신이 m을 시작할 수 채널의 끝을하기 닫기 (C)의
  • 사용 각 노동자와 코드의 ultiple 사본은 여전히합니다 (wg.Add(1); go startOrders(c, wg) 코드를 반복)

가 여기에 파이프 라인이 이동에 동시에 프로그램 배울 때 시작하기에 좋은 장소입니다 코드

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("\nStart an empty box for customer order number %d , request number %d\n", 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() 
} 
+0

이 코드를 읽는 사용자를 위해 * 총 3 개의 goroutines가 있습니다. 두 개는 명시 적으로 시작되었고 주요 goroutine 자체. –

+0

position0s에서 구조체를 전달하는 함수를 추가하려면 wg.Add (1)을 추가하면됩니다. position1s 코드를 position0s로 이동 하시겠습니까? – Danzo

+0

또한 numOrders를 5로 변경하면 첫 번째 4처럼 5 번째 상자가 채워지지 않습니다? – Danzo

1

입니다 잘 작동합니다. Nick Craig-Wood의 답변은이 특정 과제에 대한 해결 방법을 제공합니다.

Go에서 동시성을 사용하는 다른 방법이 있습니다. 여러 가지 기능의 생성 파이프 라인을 시작하는 좋은 방법입니다 - -

  • 기능 분해과 질문의 주제 : 대체로,이 동시로 취급되는 내용에 따라 나누어 세 가지 범주가 있습니다. 생각하기 쉽고 상당히 생산적입니다. 그러나 진정한 병렬 하드웨어로 진행한다면로드 균형을 맞추기가 매우 어렵습니다. 모든 것은 가장 느린 파이프 라인 스테이지의 속도로 진행됩니다.

  • 기하학적 분해 - 독립적으로 (또는 너무 많은 통신없이) 처리 할 수있는 별도의 영역으로 데이터를 나눕니다. 그리드 기반 시스템은 날씨 예보와 같은 과학적 고성능 컴퓨팅의 특정 영역에서 널리 사용됩니다.

  • 농사 - 수행 할 작업을 (많은 수의) 작업으로 잘라내어 모든 작업이 완료 될 때까지 이러한 작업을 하나씩 '작업자'에게 할당 할 수 있습니다. 종종 작업 수는 까지이 작업자 수를 초과합니다. 이 범주에는 소위 '곤란한 평행'문제 (당황 스럽네요. 고성능 시스템에 선형 속도 향상을주지 못하면 조금 어리석은 행동을하기 때문입니다.)

위의 몇 가지 종류의 네 번째 범주를 추가 할 수 있습니다.

'80 년대와 90 년대 Occam 프로그래밍의 시대를 비롯하여 많은 문헌이 있습니다. Go와 Occam은 CSP 메시지 전달을 사용하므로 문제가 비슷합니다. 도움이되는 책 Practical Parallel Processing: An introduction to problem solving in parallel (Chalmers and Tidmus 1996)을 골라 내고 싶습니다.