stesl писал(а):С таким примером у меня глаза на переносицу лезут. Пусть будет ф_ция с каким то параметром, и ты будешь натравливать на нее свои задачи. Из условия, если задача (или как правильно назвать то, что создает эта ф-ция...) ничем не занята, значит вперед. Ну и с имитацией бурной деятельности в вызываемой ф-ции (sleep подольше)
Код: Выделить всё
{$mode objfpc} {$h+} {$codepage UTF8}
uses
Windows, SysUtils;
function QueueUserWorkItem(func: LPTHREAD_START_ROUTINE; Context: pointer; Flags: ULONG): BOOL; stdcall; external kernel32;
var
runningTasks: integer; // = 0
allTasksCompleted: PRTLEvent;
i,iCount,iArtists:integer;
boZadacha:boolean;
procedure PrepareTaskQueuing;
begin
if InterlockedIncrement(runningTasks) = 1 then RTLEventResetEvent(allTasksCompleted);
end;
procedure NoteTaskCompleted;
begin
if InterlockedDecrement(runningTasks) = 0 then RTLEventSetEvent(allTasksCompleted);
end;
procedure Tasks(param: pointer); stdcall;
begin
writeln('Попытка '+intToStr(runningTasks)+' выяснить что такое симафор №' + IntToStr(GetCurrentThreadID));
while not boZadacha do sleep(1);
boZadacha := false;
inc(iCount);
writeln('поток в работе №' + IntToStr(GetCurrentThreadID));
Sleep(random(33));
writeln('выполнено (поток №' + IntToStr(GetCurrentThreadID) + ')');
NoteTaskCompleted;
boZadacha := true;
end;
begin
iCount := 0;
iArtists:=666;
allTasksCompleted := RTLEventCreate;
boZadacha := true;
for i:=1 to iArtists do begin
PrepareTaskQueuing;
writeln('Добавление задачи № '+intToStr(i));
QueueUserWorkItem(@Tasks, nil, 0);
end;
writeln(LineEnding + 'До переезда осталось 777 метров. Счётчик насчитал '+intToStr(iCount)+' художников. ');
RTLEventWaitFor(allTasksCompleted);
RTLEventDestroy(allTasksCompleted);
writeln(LineEnding + 'До переезда осталось 666 метров. Счётчик насчитал '+intToStr(iCount)+' художников. ');
writeln('Было '+intToStr(iArtists)+' художников. Исчезло '+intToStr(iArtists - iCount)+' художников. Куда исчезли художники?');
writeln('Что такое семафор - сам знаешь http://www.freepascal.ru/forum/viewtopic.php?t=27500 ');
readln;
end.
