2016-06-09 8 views
1

동기 예 비 차단 :Golang 버퍼

type job struct { 
    Id int 
    Message string 
} 

for { 
    // getJob() blocks until job is received 
    job := getJob() 
    doSomethingWithJob(job) 
} 

나는 그들이 doSomethingWithJobgetJob에서 와서 작업을 처리하고 싶습니다. 예 : getJob은 RabbitMQ/Beanstalkd와 같은 MessagingQueue에서 수신 한 페이로드이거나 HTTP 요청을 처리 할 수 ​​있습니다.

나는 doSomethingWithJob & 인 반면 getJob은 차단하고 싶지 않습니다. 그러나 나는 시스템에 과부하가 걸리지 않도록 작업 수를 제어/버퍼링하려고합니다. 예 : 최대 동시성은 5입니다.

이동 루틴의 개념은 지금 당장 혼란 스럽습니다. 따라서 올바른 방향으로 어떤 포인터를 사용하든 나를 배우는 데 도움이 될 것입니다.

업데이트 : 감사합니다. @ JimB 도움을 받으십시오. 왜 5 번 근로자는 항상 일자리를 구합니까?

jobCh := make(chan *job) 

// Max 5 Workers 
for i := 0; i < 5; i++ { 

    go func() { 

     for job := range jobCh { 
      time.Sleep(time.Second * time.Duration(rand.Intn(3))) 
      log.Println(i, string(job.Message)) 
     } 
    }() 
} 

for { 
    job, err := getJob() 
    if err != nil { 
     log.Println("Closing Channel") 
     close(jobCh) 
     break 
    } 

    jobCh <- job 
} 

log.Println("Complete") 

예 출력

2016/06/09 22:19:57 5 {"id":10692,"name":"Test Message"} 
2016/06/09 22:19:57 5 {"id":10687,"name":"Test Message"} 
2016/06/09 22:19:57 5 {"id":10699,"name":"Test Message"} 
2016/06/09 22:19:57 5 {"id":10701,"name":"Test Message"} 
2016/06/09 22:19:57 5 {"id":10703,"name":"Test Message"} 
2016/06/09 22:19:57 5 {"id":10704,"name":"Test Message"} 
+0

5 번째 작업자가 아니며, 모든 작업자는 i = 5가됩니다. 'go func (i int) {...} (i)'https://golang.org/doc/faq#closures_and_goroutines – Darigaaz

답변

4

당신은 doSomethingWithJob를 호출 채널에서 읽는 5 goroutines를 시작할 수 있습니다. 이렇게하면 동시에 처리되는 작업이 5 개를 넘지 않습니다.

jobCh := make(chan *job) 

// start 5 workers to process jobs 
for i := 0; i < 5; i++ { 
    go func() { 
     for job := range jobCh { 
      doSomethingWithJob(job) 
     } 
    }() 
} 

// send jobs to workers as fast as we can 
for { 
    jobCh <- getJob() 
} 
+0

와우 ... 나는이 모든 것을 거꾸로보고 지나치게 복잡해졌습니다! – Gravy

+0

위의 방법을 시도했습니다. 그리고 그것은 작동하지만, 작업자 5만이 작업을 수행하고있는 것처럼 보입니다. 문제의 업데이트를 참조하십시오. – Gravy

+0

@Gravy : https://golang.org/doc/faq#closures_and_goroutines. 모든 goroutine은 동일한 'i' 변수를 사용하고 있으며, i의 마지막 값은'5 '입니다. – JimB