3

Win7 x64 でこの関数と同じ機能を実装する必要があります。

最初に使用SwitchToThread()しましたが、極端な条件下でデッドロックが発生するため、これは機能しません。私が見つけることができる唯一の代替手段はSleep()、ミリ秒の解像度でしか機能しないため、これはパフォーマンスキラーである可能性が高く、LockSupport.parkNanos().

ナノ秒間隔でスレッドをスケジュールする Java の機能 (それが起こった場合) が疑わしいことがわかったので、スレッドが実行すると想定できるものを実装しました... スピン。ただし、これで問題が解決するかどうかはわかりません.Java関数が機能するにはJVMの介入が必要なように見えるため、避けられないことを遅らせているだけかもしれません。のソース コードはありませんparkNanos。ネイティブの Sun ライブラリに実装されています。

class LockSupport
{
public:
    static void ParkNanos(unsigned __int64 aNanos)
    {
        ULONGLONG start;
        ULONGLONG end;

        ::QueryUnbiasedInterruptTime(&start);
        do
        {
            // My issue with this is that nothing is actually 'Parked'.
            ::SwitchToThread();
            ::QueryUnbiasedInterruptTime(&end);
        }
        while ((end - start) < aNanos);
    }
};

呼び出しコードは次のようになります。

void SomeClass::SomeFunction()
{
    while (someCond)
    {
        LockSupport.parkNanos(1L);
    }
}

FWIW、LMAX の Disruptor パターンを C++ に移植しています。デッドロックは、あるスレッドが入っていSingleThreadedClaimStrategy::WaitForFreeSlotAt()て別のスレッドが入っているときに発生していますBlockingWaitStrategy::WaitFor(タイムアウトなし)。RingBuffer のサイズが 1、2、4、8 などのように小さい場合、デッドロックはより明白になります。

スレッドは通常のCreateThread方法で作成されます。

編集:これを書いたときはかなり遅かったので、ここにもう少し情報があります。RingBuffer は__int64s を保持します。1 つのプロデューサー スレッドと 1 つのコンシューマー スレッドがあります。Consumer スレッドは、Consumer が最後に消費したイベントのシーケンス番号を毎秒ポーリングする Timer スレッドも生成します。コンシューマーが進歩せず、プロデューサーも完了していない時点が来ます。Producer は、カウンタを公開するループを数億回実行するだけです。したがって、私の出力は次のようになります。

898
97
131
Timer: no progress
Timer: no progress
...

すべてが速度のために最適化されているリリース モードでのみ、実際に再現可能です。

4

2 に答える 2

3

unpark()スレッドへの能力に加えてLockSupport.parkNanos(...)、睡眠に過ぎません。Windows 上の OpenJDK Hotspot VM では、を使用して実装され(行 4436) WaitForSingleObject(...)、最小 1 ミリ秒スリープします。

unpark()LMAX ディスラプターはスレッドに見えません。したがって、 を呼び出すことで同等の動作が得られるはずですSleep(1)。を使用すると、よりうまくいく可能性がありSleep(0)ます。現在のスレッドで残りのタイム スライスを放棄し、すぐに再スケジュールできるようになります。SwitchToThread()これは、後者が単に「まだ実行する準備ができていないため、CPU を保持できる」と言う場合を除き、 と同等です。一方、Sleep(1)スケジューリングの粒度が十分に低い場合、実際には 1 ミリ秒一時停止することがあります。

へのコメントSleep()では、timeBeginPeriod().

于 2012-08-16T04:19:33.553 に答える
2

parkNanos のソース コードはありません。ネイティブの Sun ライブラリに実装されています。

そのネイティブ ライブラリのソース コードは、OpenJDK 6 / 7 ソース コードの一部である必要があるため、ダウンロードまたは参照できるようにする必要があります。

于 2012-08-16T02:23:48.777 に答える