1. 程式人生 > >一個用來“拉”任務的簡單執行緒池 c#版

一個用來“拉”任務的簡單執行緒池 c#版

通常用到執行緒池時,會用到“生產者-消費者”模型。

如果專案中不好實現“生產者”這一角色,而是預先開好N條執行緒,然後讓執行緒自己去“拉”任務,“拉”到有任務就處理,然後再“拉”任務,這樣實現起來很簡單,但任務的源頭若是一直沒有任務,這N條執行緒依然是不停地在“拉”,消耗著CPU資源。於是想出了以下方案:

開好N條執行緒

1.第一條執行緒在迴圈“拉”任務,其他的在阻塞(這樣就不佔CPU資源了)。

2.直到第一條執行緒拉到有任務,先“告訴”其他執行緒:我有活幹了,你們誰有空的去“源頭”把風,有活你們接著幹。

3.其中一條執行緒站了出來(簡稱第二條),同樣是迴圈“拉”任務,如果此時“源頭”還有任務,第二條執行緒同樣先“告訴”其他還在阻塞的執行緒,自己然後幹活。

4.第三條站了現來,不停在迴圈“拉”任務。

5.第一和第二條幹完活了,變成了阻塞狀態,等通知(此時在把風的執行緒)。

照著這樣的思路,用C#寫了以下模型,不知.NET庫裡是否有現成的,若有,就當學習吧

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace testMutex
{
    class Program
    {
        int threadPollMaxNUM = 3;   //最大執行緒數
        Thread thread3;
        Mutex mutex;
        object
lockObject = new object(); public Program() { mutex = new Mutex(); } static void Main(string[] args) { Program p = new Program(); p.RunThread(); } public void RunThread() { for (int i = 0
; i < threadPollMaxNUM; i++) { thread3 = new Thread(new ThreadStart(testFunc_three)); thread3.Name = "thread" + i; thread3.Start(); } string re = Console.ReadLine(); if (re == "exit") { running = false; } } private void TestFunc(string str) { Console.WriteLine("{0} {1}", str, System.DateTime.Now.Millisecond.ToString()); Thread.Sleep(50); } private void TestFunc_one(string str) { Console.WriteLine("sinco{0}{1}", str, System.DateTime.Now.Millisecond.ToString()); Thread.Sleep(5000); } //以下是彈性處理任務的模型 bool running = true; private void testFunc_three() { while (running) { mutex.WaitOne(); //bool _havaTask = false; //lock (lockObject) //{ int ix = 0; //僅作為自動退出用,實際用時不需要 bool _havaTask = false; while (_havaTask == false && running) { Console.WriteLine("{0} checking...", Thread.CurrentThread.Name); _havaTask = getOneTask(); if (_havaTask == false) { //real sleep Thread.Sleep(4000); ix++; if (ix > 5) { running = false; }//僅作為自動退出用,實際用時不需要 } } //} //'' "" mutex.ReleaseMutex(); if (_havaTask) { Console.WriteLine("{0} working...", Thread.CurrentThread.Name); //do some thing.... Thread.Sleep(5000); Console.WriteLine("{0} end !", Thread.CurrentThread.Name); } } Console.WriteLine("{0} exit !", Thread.CurrentThread.Name); } int u = 0; /// <summary> /// 假設這是一個拉任務的方法 /// </summary> /// <returns></returns> private bool getOneTask() { if (u < 6) { u++; Thread.Sleep(1000); return true; } else { //Thread.Sleep(30 * 1000); //running = false; return false; } } } }