Форум: "Начинающим";
Текущий архив: 2009.07.19;
Скачать: [xml.tar.bz2];
ВнизРаспределение потоков Найти похожие ветки
← →
Фима (2009-05-25 23:32) [0]Добрый Вечер Мастера.
Подскажите алгоритм распределения птоков.
Т.е чтоб ранить к примеру 5 потоков.
I mean:
1 Run
2 Run
3 Run
4 Run
5 Run
6 Wait for Thread
7 Wait for Thread
← →
KilkennyCat © (2009-05-26 00:11) [1]гм... и какой же должен быть алгоритм?
← →
Игорь Шевченко © (2009-05-26 00:57) [2]Семафор
← →
Германн © (2009-05-26 02:26) [3]
> Распределение потоков [D7]
>
> Фима (25.05.09 23:32)
>
> Добрый Вечер Мастера.
>
> Подскажите алгоритм распределения птоков.
>
> Т.е чтоб ранить к примеру 5 потоков.
>
> I mean:
> 1 Run
> 2 Run
> 3 Run
> 4 Run
> 5 Run
> 6 Wait for Thread
> 7 Wait for Thread
> <Цитата>
>
>
Бред!
← →
KSergey © (2009-05-26 07:59) [4]> Фима (25.05.09 23:32)
> Т.е чтоб ранить к примеру 5 потоков.
Ну так и "рань" только 5 потоков, остальные не "рань". В чем вопрос? не понятно.
← →
Фима (2009-05-26 13:32) [5]Ребята ну это же раздел для новичков ...
Может и Бред как для новичка.
Есть список TstringList;
в нём много строк
for i:=0 to list.count-1 do
begin
thread:=TParseThread.Create(list[i]);
end;
Вот как сейчас создаются потоки;
А нужно чтоб создавались по 5. Когда хоть один освободился чтоб брал следующую строчку из листа.
Вообще так...кто как может помогите...
← →
KilkennyCat © (2009-05-26 13:47) [6]
Var Kol_vo_potokov : byte = 0;
num_potoka : integer = 0;
...
if Kol_vo_potokov < 5 then
if num_potoka < list then begin
run(list[num_potoka]);
inc(num_potoka);
inc(Kol_vo_potokov);
end;
...
if terminated then dec(Kol_vo_potokov);
← →
Сергей М. © (2009-05-26 13:49) [7]
> чтоб создавались по 5. Когда хоть один освободился чтоб
> брал следующую строчку из листа
см. [2]
← →
Игорь Шевченко © (2009-05-26 14:21) [8]Изучай:
program SuperMarket;
uses
Forms,
main in "main.pas" {fMain},
Params in "Params.pas",
SuperMarketThread in "SuperMarketThread.pas",
Globals in "Globals.pas",
ShopperThread in "ShopperThread.pas";
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TfMain, fMain);
Application.Run;
end.unit Globals;
interface
uses
Windows;
var
g_hSemEntrance : THandle; //Семафор супермаркета
g_hMtxDeliCntr : THandle; //Мутекс стойки закусочной
g_hSemCheckout : THandle; //Семафор на все кассы.
implementation
end.unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, SuperMarketThread;
const
UM_ENDSIMULATION = WM_USER + 222;
type
TfMain = class(TForm)
ListBox: TListBox;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
OpenButton: TButton;
procedure OpenButtonClick(Sender: TObject);
private
procedure EndOfSimulation (Sender : TObject);
public
procedure AddToLog (const S : String);
end;
var
fMain: TfMain;
implementation
{$R *.DFM}
{ TfMain }
procedure TfMain.AddToLog(const S: String);
var
Index : Integer;
begin
Index := -1; { Make compiler happy }
repeat
try
Index := ListBox.Items.Add(S);
except
on E : EOutOfResources do
Index := -1;
end;
if Index = -1 then
ListBox.Items.Delete(0);
until Index <> -1;
ListBox.ItemIndex := Index;
end;
procedure TfMain.OpenButtonClick(Sender: TObject);
var
SuperMarket : ThreadSuperMarket;
begin
//Очищаем журнал
ListBox.Items.Clear();
//Запрещаем повторное нажатие на кнопку в процессе моделирования
OpenButton.Enabled := false;
//Перегрузка системы вызовет искажение результатов. Чтобы свести этот эффект
// к минимуму, повышаем класс приоритета этого процесса
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
//Создаем поток, моделирующий супермаркет
SuperMarket := ThreadSuperMarket.Create(true);
with SuperMarket do begin
OnTerminate := EndOfSimulation;
FreeOnTerminate := true;
Resume();
end;
end;
procedure TfMain.EndOfSimulation(Sender: TObject);
begin
//Конец моделирования, установим нормальный приоритет
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
OpenButton.Enabled := true;
end;
end.unit Params;
interface
uses
Windows;
var
g_nMaxOccupancy : Integer;
g_nTimeOpen : DWORD;
g_nCheckoutCounters : Integer;
g_nMaxDelayBetweenShopperCreation : Integer;
g_nMaxWaitToGetInMarket : Integer;
g_nMaxTimeShopping : Integer;
g_nMaxWaitForDeliCntr : Integer;
g_nMaxTimeSpentAtDeli : Integer;
g_nMaxTimeAtCheckout : Integer;
implementation
initialization
g_nMaxOccupancy := 30;
g_nCheckoutCounters := 5;
g_nTimeOpen := 1500;
g_nMaxDelayBetweenShopperCreation := 300;
// Параметры покупателя
g_nMaxWaitToGetInMarket := 20;
g_nMaxTimeShopping := 80;
g_nMaxWaitForDeliCntr := 20;
g_nMaxTimeSpentAtDeli := 70;
g_nMaxTimeAtCheckout := 60;
end.
← →
Игорь Шевченко © (2009-05-26 14:21) [9]
unit ShopperThread;
interface
uses
Classes;
type
TThreadShopper = class(TThread)
private
FShopperEventMessage : String;
procedure LogShopperEvent();
protected
procedure Execute; override;
public
ShopperId : Integer;
end;
implementation
uses
Windows, SysUtils, main, Params, Globals;
{ TThreadShopper }
procedure TThreadShopper.Execute;
var
Duration : Integer;
rc : Integer;
begin
//Ждем, когда покупатель войдет в магазин
Duration := Random(g_nMaxWaitToGetInMarket);
FShopperEventMessage := Format("Жду у входа в магазин %d тиков.", [Duration]);
Synchronize(LogShopperEvent);
rc := WaitForSingleObject(g_hSemEntrance, Duration);
if rc = WAIT_TIMEOUT then begin
FShopperEventMessage := "Надоело ждать, ушел домой";
Synchronize(LogShopperEvent);
Exit;
end;
//Покупатель вошел в супермаркет, пора заняться продуктами
Duration := Random(g_nMaxTimeShopping);
FShopperEventMessage := Format("Покупаю в течении %d тиков.", [Duration]);
Synchronize(LogShopperEvent);
Sleep(Duration);
//Покупки закончены. Один к трем, что покупатель подойдет к стойке закусочной
if Random(2) = 0 then begin
//Подошел...
Duration := Random(g_nMaxWaitForDeliCntr);
FShopperEventMessage := Format("Жду обслуживания в закусочной %d тиков.",
[Duration]);
Synchronize(LogShopperEvent);
rc := WaitForSingleObject(g_hMtxDeliCntr, Duration);
if rc = 0 then begin
//Сделал заказ
Duration := Random(g_nMaxTimeSpentAtDeli);
FShopperEventMessage := Format("Закусываю в течение %d тиков.",
[Duration]);
Synchronize(LogShopperEvent);
Sleep(Duration);
//Покинул стойку
ReleaseMutex(g_hMtxDeliCntr);
end else begin
//Устал ждать, продолжил покупки
FShopperEventMessage := "Устал ждать в закусочной.";
Synchronize(LogShopperEvent);
end;
end else begin
FShopperEventMessage := "Не пошел закусывать.";
Synchronize(LogShopperEvent);
end;
//Встал в очередь к кассе
FShopperEventMessage := "Стою в очереди в кассу.";
Synchronize(LogShopperEvent);
WaitForSingleObject(g_hSemCheckout, INFINITE);
//Расплачивается
Duration := Random(g_nMaxTimeAtCheckout);
FShopperEventMessage := Format("Расплачиваюсь в течение %d тиков.",
[Duration]);
Synchronize(LogShopperEvent);
Sleep(Duration);
//Расплатился, отходит от кассы
FShopperEventMessage := "Расплатился.";
Synchronize(LogShopperEvent);
ReleaseSemaphore(g_hSemCheckout, 1, nil);
//Уходит из магазина
FShopperEventMessage := "Ушел из магазина.";
Synchronize(LogShopperEvent);
ReleaseSemaphore(g_hSemEntrance, 1, nil);
//Конец потока-покупателя
end;
procedure TThreadShopper.LogShopperEvent;
begin
fMain.AddToLog(Format("%.4d: %s", [ShopperId, FShopperEventMessage]));
end;
end.unit SuperMarketThread;
interface
uses
Windows, Classes;
type
ThreadSuperMarket = class(TThread)
private
FRawMessage : String;
CloseTime : DWORD;
procedure LogOpenShop;
procedure LogWaitShoppers;
procedure LogRawMessage;
procedure LogCloseShop;
procedure SendEndOfSimulation;
protected
procedure Execute; override;
end;
implementation
uses
SysUtils, Messages, main, Params, Globals, ShopperThread;
{ ThreadSuperMarket }
procedure ThreadSuperMarket.Execute;
var
AShopperId : Integer;
Shopper : TThreadShopper;
CurrentShoppers : Integer;
begin
AShopperId := 0;
g_hSemEntrance := CreateSemaphore(
nil, //Атрибуты защиты
0, //Счетчик блокировки входа
g_nMaxOccupancy, //Максимальное число покупателей,
//которое может находиться в магазине
nil); //Семафор без имени
g_hMtxDeliCntr := CreateMutex(
nil, //Атрибуты защиты
false, //Изначально у стойки закусочной никого нет
nil); //Мутекс без имени
g_hSemCheckout := CreateSemaphore(
nil, //Атрибуты защиты
g_nCheckoutCounters, //Все кассы свободны
g_nCheckoutCounters, //Всего касс в магазине
nil); //Семафор без имени
//Открываем магазин...
Synchronize(LogOpenShop);
ReleaseSemaphore(g_hSemEntrance, g_nMaxOccupancy, nil);
//Узнаем время, в которое надо прекратить создание потоков-покупателей
CloseTime := GetTickCount() + g_nTimeOpen;
//До закрытия магазина работаем...
while (GetTickCount() < CloseTime) do begin
//Создаем поток, моделирующий покупателя
Inc(AShopperId);
Shopper := TThreadShopper.Create(true);
with Shopper do begin
FreeOnTerminate := true;
ShopperId := AShopperId;
Resume();
end;
Sleep(Random(g_nMaxDelayBetweenShopperCreation));
end;
//Супермаркет пора закрывать, ждем ухода оставшихся покупателей
Synchronize(LogWaitShoppers);
for CurrentShoppers:=1 to g_nMaxOccupancy do begin
WaitForSingleObject(g_hSemEntrance, INFINITE);
FRawMessage := Format("-> %d покупателей не в магазине.",
[CurrentShoppers]);
Synchronize(LogRawMessage);
end;
Synchronize(LogCloseShop);
CloseHandle(g_hSemCheckout);
CloseHandle(g_hMtxDeliCntr);
CloseHandle(g_hSemEntrance);
//Уведомляем основной поток об окончании моделирования
Synchronize(SendEndOfSimulation);
end;
procedure ThreadSuperMarket.LogCloseShop;
begin
fMain.AddToLog("-> Магазин закрылся - конец моделирования.");
end;
procedure ThreadSuperMarket.LogOpenShop;
begin
fMain.AddToLog("-> Магазин открывается для покупателей.");
end;
procedure ThreadSuperMarket.LogRawMessage;
begin
fMain.AddToLog(FRawMessage);
end;
procedure ThreadSuperMarket.LogWaitShoppers;
begin
fMain.AddToLog("-> Магазин закрывается, ");
fMain.AddToLog(" ждем пока покупатели расплатятся.");
end;
procedure ThreadSuperMarket.SendEndOfSimulation;
begin
PostMessage(fMain.Handle, UM_ENDSIMULATION, 0, 0);
end;
end.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.07.19;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.004 c