2

一部の言語ではミューテックス ロックが提供されていないため、自分でビルドする必要があります。私は通常、次のようなコードを書きます。

oldval = 0;
newval = 1;
//suggest there was a Compare And Set operation that make only one thread return true,if no CAS operation , call any other language module that can offer a cas instead
while (!CAS(*somepointer,oldval,newval)) {
     //lock failed
     sleep(1000); //sleep one second or some value really depend on what you are doing.
}
//lock succeed, do something....
*somepointer = oldval; //release lock.

当然sleep処理速度は遅くなりますが、sleepを破棄すると… スレッドの切り替えが頻繁になりすぎてパフォーマンスが低下するのではないか?深く考えると、どのようにsleep実装されていますか? 彼らがこのようなことをしたら...

expired = getCurrentTime() + sleepTime;
while (getCurrentTime() < expired) { }

...これは事態を悪化させるだけです。

sleepスレッドをしばらく一時停止する必要がある場合にのみ使用する必要があると思うので、私の場合は間違っているかもしれません。

4

1 に答える 1

3

sleep()および関連する関数は、OS が設定された時間内にプロセスをウェイクアップするように要求する OS へのシステム コールを作成します。OS は、特定のケース (シグナル/例外の受信など) でプロセスをより早く起動することがありますが、それ以外の場合、待機中のプロセスの CPU 使用率はゼロになります。

OS は、すべてのプロセスがスリープしている (または何らかのタイムアウトでブロックされている) ことを検出した場合、ハードウェア固有の命令を使用して、割り込み (クロック割り込み、DMA 割り込みなど) までプロセッサをスリープ状態にすることで、OS 自体をスリープ状態にすることができます。受けます。

OS が提供する同期プリミティブも同様に機能します。たとえば、ミューテックスをロックするように要求すると、ミューテックスがロック解除されるまでスレッドをスリープ状態にするシステム コールが発生します。アンロックもシステムコールを経由する必要があるため、OS はミューテックスがアンロックされていることを認識します。

を使用sleepすると、単純なビジー待機ループと比較して CPU の使用量が大幅に少なくなります。ただし、OS は、セマフォやロックなど、少なくともいくつかの同期プリミティブを提供している可能性があります (組み込みシステムでさえ、何らかの方法でスレッドをサポートしている場合はこれらを提供することがよくあります)。独自の機能を試す前に、OS がこれらの機能を提供しているかどうかを調べる必要があります。OS が提供する同期プリミティブを使用すると、アプリケーションのパフォーマンスと応答性が向上します。

重要な注意: ベアメタル組み込みプラットフォームで開発している場合、sleepスレッドをスリープ状態にする OS スケジューラがないため、ライブラリは実際には (Arduino などの場合のように) ビジー状態で待機している可能性があります。この場合、プロセッサの使用を最小限に抑えることが重要な場合 (たとえば、消費電力を削減するため)、ライブラリで提供されていない場合は、CPU を一時停止するプロセッサ固有の方法を見つける必要があります。

于 2012-09-16T01:07:13.910 に答える