2013-08-16 4 views
21

Yahooを利用して、Yahoo Financialから株価スプレッドシートをダウンロードしたいと思います。私は自分のゴルーチンのすべての株式についてhttpリクエストをしています。私は約2500シンボルのリストを持っていますが、2500リクエストを並行して作るのではなく、一度に250を作るのが好きです。 Javaではスレッドプールを作成し、スレッドが解放されたときにスレッドを再利用します。私は似たようなものを見つけようとしていました.Goroutineプールがあれば、それでもリソースは見つけられませんでした。私は、誰かが手作業でその仕事を達成する方法を教えてくれるか、私に同じもののためのリソースを教えてもらえるかどうか、感謝しています。ありがとう!goroutineプールの使い方

+0

プールでこれらのゴルーチンが必要ですか?のように、作成して再利用するリソースのように扱います。または、ゴルーチンが使い捨てである単純なソリューションを検討しますが、一度に実行されているのはどれだけの数になっていますか? – atedja

答えて

41

最も簡単な方法は、250個のゴルーチンを作成し、メインのゴルーチンからチャイルドへのリンクを渡してそのチャンネルを聞くために使用できるチャンネルを渡すことです。

すべてのリンクがゴルーチンに渡されると、チャンネルを閉じ、すべてのゴルーチンが仕事を終了するだけです。

子供がデータを処理する前にメインのゴルーチンから身を守るために、sync.WaitGroupを使用できます。ここで

は説明するいくつかのコードである(ない最終作業バージョンが、ポイントを示して)の上に私が言われている:あなたはこの git repo

からGoでスレッドプールの実装ライブラリを使用することができます

func worker(linkChan chan string, wg *sync.WaitGroup) { 
    // Decreasing internal counter for wait-group as soon as goroutine finishes 
    defer wg.Done() 

    for url := range linkChan { 
    // Analyze value and do the job here 
    } 
} 

func main() { 
    lCh := make(chan string) 
    wg := new(sync.WaitGroup) 

    // Adding routines to workgroup and running then 
    for i := 0; i < 250; i++ { 
     wg.Add(1) 
     go worker(lCh, wg) 
    } 

    // Processing all links by spreading them to `free` goroutines 
    for _, link := range yourLinksSlice { 
     lCh <- link 
    } 

    // Closing channel (waiting in goroutines won't continue any more) 
    close(lCh) 

    // Waiting for all goroutines to finish (otherwise they die as main routine dies) 
    wg.Wait() 
} 
+3

このコードの実際の小規模なテストは次のとおりです。http://play.golang.org/p/fruJiGBWjn – Druska

1

Hereは、ブログからスレッドプールとして

スニペットをチャネルを使用する方法についての素晴らしいブログです

var (
MaxWorker = os.Getenv("MAX_WORKERS") 
MaxQueue = os.Getenv("MAX_QUEUE") 
) 

//Job represents the job to be run 
type Job struct { 
    Payload Payload 
} 

// A buffered channel that we can send work requests on. 
var JobQueue chan Job 

// Worker represents the worker that executes the job 
type Worker struct { 
    WorkerPool chan chan Job 
    JobChannel chan Job 
    quit  chan bool 
} 

func NewWorker(workerPool chan chan Job) Worker { 
    return Worker{ 
     WorkerPool: workerPool, 
     JobChannel: make(chan Job), 
     quit:  make(chan bool)} 
} 

// Start method starts the run loop for the worker, listening for a quit channel in 
// case we need to stop it 
func (w Worker) Start() { 
    go func() { 
     for { 
      // register the current worker into the worker queue. 
      w.WorkerPool <- w.JobChannel 

      select { 
      case job := <-w.JobChannel: 
       // we have received a work request. 
       if err := job.Payload.UploadToS3(); err != nil { 
        log.Errorf("Error uploading to S3: %s", err.Error()) 
       } 

      case <-w.quit: 
       // we have received a signal to stop 
       return 
      } 
     } 
    }() 
} 

// Stop signals the worker to stop listening for work requests. 
func (w Worker) Stop() { 
    go func() { 
     w.quit <- true 
    }() 
} 
関連する問題