看到一個文章, 好玩, 學習著實現了一下 呵呵
情境如下:
公司同事排隊上廁所, 如果廁所有空位, 優先考慮領導使用, 然後才是普通員工按排隊順序使用
---------------------------------------------------------------------------------------------------------------------------
單元檔案
unit utThreadPool;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls;type TForm_CatchWC = class(TForm) lvWC: TListView; lvEmploye: TListView; btnAddWC: TButton; btnAddEmploye: TButton; btnAddM: TButton; btnStart: TButton; procedure FormCreate(Sender: TObject); procedure btnStartClick(Sender: TObject); procedure btnAddWCClick(Sender: TObject); procedure btnAddEmployeClick(Sender: TObject); procedure btnAddMClick(Sender: TObject); private { Private declarations } hMutex : THandle; //互斥控制代碼 WCArr : array of dword; //廁所 myMsg : dword; //自訂訊息 FActived : boolean; //是否開搶 WC, Employe : integer; //當前廁所與員工的匹配情況 //添加員工 procedure AddEmploye(const ARoleName: string); public { Public declarations } end;var Form_CatchWC: TForm_CatchWC;implementation{$R *.dfm}//使用WC 每人限用50秒function UseWC(index : integer): integer; stdcall;var i, vWC, vEmploye : integer; msg : TMsg;begin while GetMessage(msg, 0, 0, 0) do begin if msg.message = Form_CatchWC.myMsg then begin vEmploye := Form_CatchWC.Employe; vWC := Form_CatchWC.WC; for i := 1 to 50 do begin sleep(200); WaitForSingleObject(Form_CatchWC.hMutex,INFINITE); Form_CatchWC.lvEmploye.Items.Item[vEmploye].SubItems[2] := inttostr(i); ReleaseMutex(Form_CatchWC.hMutex); end; Form_CatchWC.lvWC.Items[vWC].SubItems[0] := '空閑'; end; end;end;//分配WC 優先經理Mfunction AssignWC(index : integer): integer; stdcall;var i, j : integer; JobFound : boolean;begin while true do begin sleep(500); if Form_CatchWC.FActived then begin JobFound := False; for i := 0 to Form_CatchWC.lvWC.Items.Count - 1 do begin if Form_CatchWC.lvWC.Items[i].SubItems[0] = '空閑' then begin //經理優先 for j := 0 to Form_CatchWC.lvEmploye.Items.Count - 1 do begin if (Form_CatchWC.lvEmploye.Items[j].SubItems[0] = 'M') and (Form_CatchWC.lvEmploye.Items[j].SubItems[1] = '等待') then begin //可以如廁時, WC牌號和員工牌號 Form_CatchWC.WC := i; Form_CatchWC.Employe := j; //調整員工, WC狀態 Form_CatchWC.lvWC.Items.Item[i].SubItems[0] := '使用'; Form_CatchWC.lvEmploye.Items.Item[j].SubItems[1] := '入廁'; //給線程發送訊息, 告知如廁 PostThreadMessage(Form_CatchWC.WCArr[i], Form_CatchWC.myMsg, 0, 0); //當前廁所已佔用, 只能找其他廁所了 JobFound := True; break; end; end; if JobFound then Break; //經理先蹲, 然後員工 for j := 0 to Form_CatchWC.lvEmploye.Items.Count - 1 do begin if (Form_CatchWC.lvEmploye.Items[j].SubItems[0] = 'E') and (Form_CatchWC.lvEmploye.Items[j].SubItems[1] = '等待') then begin Form_CatchWC.WC := i; Form_CatchWC.Employe := j; Form_CatchWC.lvWC.Items.Item[i].SubItems[0] := '使用'; Form_CatchWC.lvEmploye.Items.Item[j].SubItems[1] := '入廁'; PostThreadMessage(Form_CatchWC.WCArr[i], Form_CatchWC.myMsg, 0, 0); JobFound := True; break; end; end; end; if JobFound then break; end; end; end;end;procedure TForm_CatchWC.AddEmploye(const ARoleName : string);var item : TListItem; i : integer; uThread : THandle;begin //增加員工等待線程 SetLength(WCArr, Length(WCArr) + 1); CreateThread(nil, 0, @UseWC, nil, 0, uThread); WCArr[Length(WCArr) - 1] := uThread; with lvEmploye.Items.Add do begin Caption := '員工' + inttostr(Length(WCArr) - 1); SubItems.Add(ARoleName); SubItems.Add('等待'); SubItems.Add('0'); end;end;procedure TForm_CatchWC.btnAddEmployeClick(Sender: TObject);begin AddEmploye('E');end;procedure TForm_CatchWC.btnAddMClick(Sender: TObject);begin AddEmploye('M');end;procedure TForm_CatchWC.btnAddWCClick(Sender: TObject);begin with lvWC.Items.Add do begin Caption := '廁所' + inttostr(lvWC.Items.Count + 1); SubItems.Add('空閑'); end;end;procedure TForm_CatchWC.btnStartClick(Sender: TObject);begin FActived := True;end;procedure TForm_CatchWC.FormCreate(Sender: TObject);var uThread : dword; i : integer; item : TListItem;begin hMutex := CreateMutex(0, false,'hMutex'); myMsg := WM_USER + 1; lvWC.Clear; with lvWC.Items.Add do begin Caption := '廁所' + inttostr(lvWC.Items.Count); SubItems.Add('空閑'); end; lvEmploye.Clear; AddEmploye('E'); AddEmploye('E'); AddEmploye('M'); //建立分配廁所的線程 windows.CreateThread(nil,0,@AssignWC,nil,0,uThread); FActived := False;end;end.
表單檔案
object Form_CatchWC: TForm_CatchWC Left = 0 Top = 0 Caption = #25250#21397#25152 ClientHeight = 247 ClientWidth = 705 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object lvWC: TListView Left = 8 Top = 8 Width = 233 Height = 225 Columns = < item Caption = #21397#25152#32534#21495 end item Caption = #20351#29992#29366#24577 end> Items.ItemData = { 05200000000100000000000000FFFFFFFFFFFFFFFF00000000FFFFFFFF000000 0003955340623100} TabOrder = 0 ViewStyle = vsReport end object lvEmploye: TListView Left = 247 Top = 8 Width = 306 Height = 225 Columns = < item Caption = #21592#24037#32534#21495 end item Caption = #32844#20301 end item Caption = #24403#21069#29366#24577 end item Caption = #35745#26102 end> Items.ItemData = { 05200000000100000000000000FFFFFFFFFFFFFFFF00000000FFFFFFFF000000 00035854E55D3100} TabOrder = 1 ViewStyle = vsReport end object btnAddWC: TButton Left = 622 Top = 112 Width = 75 Height = 25 Caption = #22686#21152#21397#25152 TabOrder = 2 OnClick = btnAddWCClick end object btnAddEmploye: TButton Left = 622 Top = 16 Width = 75 Height = 25 Caption = #21592#24037#25490#38431 TabOrder = 3 OnClick = btnAddEmployeClick end object btnAddM: TButton Left = 622 Top = 64 Width = 75 Height = 25 Caption = #32463#29702#25490#38431 TabOrder = 4 OnClick = btnAddMClick end object btnStart: TButton Left = 622 Top = 160 Width = 75 Height = 25 Caption = #24320#22987#25250#21397#25152 TabOrder = 5 OnClick = btnStartClick endend