2016-09-30 6 views
1

私は私が打つことができる回数を制限したい、私の現在の実装では、ウェブサイトを取得するために、10のゴールーチンを使用しています制限回数のpingホスト名毎秒

行く学ぶためのWebクローラを書いています毎秒ホスト名。

これを実行するための最良の(スレッドセーフな)アプローチは何ですか。

+1

コードの例を投稿してください –

+1

を参照してください。Golangで何秒間コマンドを実行するのですか?http://stackoverflow.com/questions/39385883/how-do-i-execute-commands-many-manyゴートン・イン・ゴーラン –

答えて

1

channelには、座標調整に使用できる同時同期メカニズムがあります。 time.Tickerと連携して、指定された数の関数呼び出しを定期的にディスパッチすることができます。

// A PeriodicResource is a channel that is rebuffered periodically. 
type PeriodicResource <-chan bool 

// The NewPeriodicResourcePool provides a buffered channel that is filled after the 
// given duration. The size of the channel is given as count. This provides 
// a way of limiting an function to count times per duration. 
func NewPeriodicResource(count int, reset time.Duration) PeriodicResource { 
    ticker := time.NewTicker(reset) 
    c := make(chan bool, count) 

    go func() { 
     for { 
      // Await the periodic timer 
      <-ticker.C 

      // Fill the buffer 
      for i := len(c); i < count; i++ { 
       c <- true 
      } 
     } 
    }() 

    return c 
} 

単一のgoルーチンは、各テロップイベントを待って、最大容量までバッファされたチャネルを埋めるように試みます。コンシューマがバッファを使い切っていない場合、連続したティックはそれをリフィルするだけです。チャネルを使用して、最大でn回、時間、の動作を同期して実行することができます。たとえば、doSomething()を1秒間に5回以上呼び出すことはできません。

r := NewPeriodicResource(5, time.Second) 
for { 
     // Attempt to deque from the PeriodicResource 
     <-r 

     // Each call is synchronously drawing from the periodic resource 
     doSomething() 
} 

当然、同じチャネルが当たり最もプロセスにファンアウトだろうgo doSomething()を呼び出すために使用することができます。

関連する問題