多線程實現廁所排號

看到一個帖子, 好玩, 學習着實現了一下  呵呵


場景如下:

公司同事排隊上廁所, 如果廁所有空位, 優先考慮領導使用, 然後纔是普通員工按排隊順序使用

---------------------------------------------------------------------------------------------------------------------------


單元文件

unit utThreadPool;

interface

uses
  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  優先經理M
function 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
  end
end

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章