1

タスクを 1 時間に 1 回実行したいが、1 時間中の可変時間に実行したいとします。完全にランダムである必要はありません。たとえば、毎正時にやりたくないだけです。そして、1時間に1回だけやりたいです。

これにより、30 分から 90 分のランダムな時間スリープしてから再びスリープするなど、いくつかの明白なアプローチが排除されます。タスクが 30 分強のスリープ状態で連続して数回実行される可能性はあります (かなりの可能性があります)。

私が考えているアプローチは次のようになります: 1 時間ごとに、その時間の Unix タイムスタンプをハッシュし、結果を 3600 で変更します。その結果をその時間の Unix タイムスタンプに追加すると、その時点でタスクが実行されます。擬似コード:

while now = clock.tick; do
  // now = a unix timestamp
  hour = now - now % 3600;
  hash = md5sum(hour);
  the_time = hour + hash % 3600;
  if now == the_time; then
    do_the_work();
  end
end

これは私の要件を満たすと確信していますが、この質問を投げ捨てて、他の人がどんなアイデアを持っているかを見るのは楽しいだろうと思いました!

4

3 に答える 3

1

次の 1 時間で作業を行うには、その時間内のランダムな分を選択します。

つまり、作業を行う次の間隔のランダムな時間を選択します。作業が前の間隔から持ち越された場合、これは現在の間隔 (時間) と同じ間隔 (時間) になる可能性があります。

「寝る時間」は、それまでの時間です。これは、ランダムな時間が今より前の場合、持ち越しの状況で「すぐに」実行することもできます。これにより、作業に 1 時間以上かかる場合を除き、1 時間ごとにランダムな時間が確実に選択されます。

必要以上に複雑にしないでください。ここでハッシュしたり、いじったりする理由はありませんrandom。これが、SharePoint タイマー (1 時間ごとのスケジュール) などの「エンタープライズ」ソリューションのしくみです。

于 2013-02-12T01:05:21.207 に答える
0
  1. 毎正時に実行するように (cron などを使用して) タスクをスケジュールします。

  2. タスクの開始時に、0 から (60 - (タスクの推定実行時間+ファッジ ファクター)) 分のランダムな時間スリープします。

  3. タスクを同時に 2 回実行したくない場合は、pid ファイルを使用できます。タスクは、スリープ後にこのファイルをチェックし、現在実行中のタスクが終了するのを待ってから再開できます。

于 2013-02-12T01:05:06.800 に答える
0

提案されたソリューションを展開しましたが、非常にうまく機能しています。たとえば、1 分間に 1 回、監視しているプロセスからいくつかの情報をサンプリングしますが、1 分間のさまざまな時間にサンプリングします。Go コードで、次のように RandomlyWithin と呼ばれる Timestamp 型のメソッドを作成しました。

func (t Timestamp) RandomlyWithin(dur Timestamp, entropy ...uint32) Timestamp {
    intervalStart := t - t % dur
    toHash := uint32(intervalStart)
    if len(entropy) > 0 {
        toHash += entropy[0]
    }
    md5hasher.Reset()
    md5hasher.Write([]byte{
        uint8(toHash >> 24 & 255),
        uint8(toHash >> 16 & 255),
        uint8(toHash >> 8 & 255),
        uint8(toHash & 255)})
    randomNum := binary.BigEndian.Uint32(md5hasher.Sum(nil)[0:4])
    result := intervalStart + Timestamp(randomNum)%dur
    return result
}
于 2013-02-13T11:11:04.143 に答える