ホームページ  >  記事  >  バックエンド開発  >  C# がスレッドプール機能を単体で実装する (2)

C# がスレッドプール機能を単体で実装する (2)

黄舟
黄舟オリジナル
2016-12-27 14:37:351517ブラウズ

はじめに

前回の記事「C#でスレッドプール機能を実装する(1)」では、基本的に実行できるプログラムを実装しましたが、実際にはスレッドプールとは言えません。前回の記事のコードには致命的なバグがあり、タスクがない場合は待機せずに、狂ったように while ループが実行され、タスク リストをロックしようとします。パフォーマンスが非常に低く、プログラムの応答速度が非常に遅い (新しいタスクが追加されると、ジョブの実行が開始されるまでに時間がかかる) のは、先ほど述べたとおりです。

この問題を解決するには、何らかの方法を使用してプログラムがプロセスを同期できるようにする必要があります。

方法 1

セマフォを使用する

タスクのロック操作を減らすために、タスクが空でない場合にのみテストします。セマフォはタスク テーブル内の番号を表します。 s.WaitOne(); が成功すると、タスクのロックと取り出しが開始されます

while (flag && TaskQueue != null)
            {
                //等待任务
                ThreadPoolManager.s.WaitOne();
                //获取任务
                lock (TaskQueue)
                {
                    try
                    {
                        if (TaskQueue.Count > 0)
                            task = TaskQueue.Dequeue();
                        else
                            task = null;
                    }
                    catch (Exception)
                    {
                        task = null;
                    }
                    if (task == null)
                        continue;

ThreadPoolManager クラスに 2 つの変数を追加し、セマフォ s = を初期化します。このクラスを初期化するときに new Semaphore(0, MaxJobNum);


この方法で同期を実現できます

テストクラスを以下に示します

//由于采用信号量需要定义一个
        public int MaxJobNum = 1000;
        public static Semaphore s;

dec84560c9faf01534a3d51a48a62869vcD4KPGgxPre9t6i2/jwvaDE+Cs7Sw8eyu8rH08PQxbrFwb+jrM7Sw8fKudPDQXV0b1Jlc2V0RXZlbnTAtMq1z9bNrLK9Cjxicj4KCrXa0ruyvaOs1N pUaHJlYWRQb2 9sTWFuYWdlcrP1yry7r8qxuvK0tL2o0ru49iAgbG9ja3MgPSBuZXcgQXV0b1 Jlc2V0RXZlbnQoZmFsc2UpOwq1sUFkZFRhc2u1xMqxuvJsb2Nrcy5TZXQoKTvNqNqtci0/b XEstnX96GjCsi7uvPO0s PHttRXb3JrVGhyZWFktcRydW66r8r91/bSu7j20KHQobXE0N64xAo8cHJlIGNsYXNzPQ=="brush:java;"> public void run() { while (flag && TaskQueue != null) { //タスクを待機中//ThreadPoolManager.sep.WaitOne(); //タスクを待機中 (TaskQueue.Count == 0 && flag) { try { ThreadPoolManager.locks.WaitOne() }; { } } //タスクロックを取得します (TaskQueue) { try { task = TaskQueue.Dequeue(); } catch (Exception) { task = null } if (task == null) continue { task.SetEnd( false) ); task.StartTask(); } catch (例外) { } try { if (!task.IsEnd()) { task.EndTask(); } } / /end of while }タスクリストの数が0の場合のみ、AddTaskまでブロックして続行します


上記は、C#のスレッドプール関数の独自実装(2)の内容です。 PHP 中国語ネット (www.php.cn) へ!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。