3

ZeroMQ を使用してメッセージを送受信する単純なコンソール アプリケーションがあります。受信部分には、次のメッセージ ポンプ コードがあります。

   ZMQ.Context _context = new ZMQ.Context(1);

   ZMQ.PollItem[] pollItems = new ZMQ.PollItem[0];

   while (!_finished)
   {
       if (pollItems.Length > 0)
           context.Poll(pollItems, pollTimeout);
       else
           Thread.Sleep(1);

       if (_receiversChanged)
           UpdatePollItems(ref pollItems);
   }

(レシーバーを追加する必要があるため、実行時にポーラーからアイテムを追加および削除できるという考え方です。UpdatePollItems は、レシーバーのセットが変更されるたびに新しい配列を作成するだけです。)

pollTimeout の値を 50ms と 500ms にしてみましたが、アプリ (Console.ReadKey のメイン スレッドにある) は、メッセージが送信されていない場合でも、1 つのコアを 100% 使用します。プロファイラーの下でアプリを実行し、すべての CPU をかみ砕いているのが ZMQ.Context.Poller であることを確認しました。

他の人も同様の行動を見たことがありますか? 最新の ZeroMQ C# バインディング (NuGet の clrzmq-x64.2.2.3) を使用しています。

4

2 に答える 2

4

ポーリング タイムアウトを 500 ミリ秒に設定していると言うとき、変数 pollTimeout を 500 に設定していると推測します。これは正しくありません。500 ミリ秒のタイムアウトの場合、変数 pollTimeout を 500000 に設定する必要があります。context.Poll(...,500) を実行すると、500 usec と解釈され、内部で 0 ミリ秒に丸められます。

自分のシステムで、ポーリングに 500 を渡すと CPU 使用率が 90 ~ 100% になることを確認しました。値を 1000 を超える値に設定すると、CPU 使用率が大幅に低下し、500000 (500 ミリ秒) の場合は無視できます。

いずれにしても、コード サンプルを変数 pollTimeout の初期化に更新してください。私が完全に基地から外れている場合、少なくとも他の回答者がこの道を進むのを防ぐことができます.

于 2012-09-10T23:37:04.160 に答える
4

はい、ドライバーにバグがあります。私もそれを打ちました。コードを見ると、.net 4 バージョンの方がうまくいく可能性がありますが、再コンパイルする必要があります。書き直したコードがプルリクエストとして再統合できるかどうかを確認します。

于 2012-04-06T09:00:29.850 に答える