Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.03;
Скачать: CL | DM;

Вниз

Как узнать количество потоков работающих в данный момент времени   Найти похожие ветки 

 
image   (2006-11-10 01:53) [0]

При написании многопотокового сканера сети, столкнулся с такой проблеммой. Программа создает 255 потоков, которые производят пинг (использую библиотеку компонентов ics - Ping). За 2-3 сек выводит IP-адреса найденных ПК, Timeout-ы и имена ПК, но результаты нестабильные, создается впечатление что потоки мешают друг другу.     Нестабильность проявляется в том, что количество найденных ПК колеблется, и чем слабее ПК, тем больше разница.  Я думаю что необходимо проконтролировать количество одновременно запущенных потоков, т.е. ограничить их количество  например до 16-32, но незнаю как это сделать. Подскажите пожалуйста как создать счетчик запущенных процессов


 
Ketmar ©   (2006-11-10 02:31) [1]

пардон, нафига тебе счётчик процессов? считай потоки. ты создаёшь -- ты и считай. с Inc() и Dec() знаком?


 
MikePetrichenko ©   (2006-11-10 02:38) [2]


> ограничить их количество  например до 16-32

Пользуй семафор


 
Ketmar ©   (2006-11-10 02:41) [3]

>[2] MikePetrichenko(c) 10-Nov-2006, 02:38
>Пользуй семафор
не пугай человека. %-)


 
MikePetrichenko ©   (2006-11-10 02:48) [4]


> не пугай человека. %-)

Хай привыкает.
Я его даже добью:

Semaphore := CreateSemaphore(nil, 4, 4, nil);

for Loop := 0 to FDevices.Count - 1 do
 with FTask do
   Threads.Add(TSendThread.Create(Path, FDevices[Loop], Message.Files, Settings.vCard.Get, Settings.vCard.Put, vCardFileName, Semaphore, FTask.Message.ID));

 while Threads.Count > 0 do begin
   TThread(Threads[0]).WaitFor;
   Threads.Delete(0);
 end;

 CloseHandle(Semaphore);


И в потоке по завершению:


ReleaseSemaphore(FSemaphore, 1, nil);


P.S. Только не спрашивай откуда это и почему именно так. Долго буду объяснять.


 
Ketmar ©   (2006-11-10 02:56) [5]

>[4] MikePetrichenko(c) 10-Nov-2006, 02:48
>Я его даже добью:
"голосы за кадром: убыв, убыв!" (ц) Л.П.

>P.S. Только не спрашивай откуда это и почему именно так.
не буду. мне и без пояснений уже страшно. %-)


 
image   (2006-11-10 03:05) [6]

>пардон, нафига тебе счётчик процессов? считай потоки. ты создаёшь -- ты >и считай. с Inc() и Dec() знаком?

  Дело в том, что потоки у меня создаются в цикле, вводишь диапазон адресов и пуск, а я хочу сделать так, чтобы можно было контролировать количество создаваемых потоков. Создал 16 потоков ждешь. Как только один поток из 16 отработал, тут же создаешь следующий.
 И там у меня еще если ПК найден, то тут же создается поток, который определяет имя ПК. Получается если найдено 255 ПК то создаются 255 потоков определяющих их имена. 500 потоков многовато.


 
Джо ©   (2006-11-10 03:11) [7]

> [6] image   (10.11.06 03:05)

Ну, так создай специальный класс-менеджер потоков. Пускай он их и создает и считает, при необходимости откладывая создание следующего. В чем проблема-то?


 
Ketmar ©   (2006-11-10 03:12) [8]

обалдеть. спрячь. а лучше сожги.
а) на кой фиг определять имя в отдельном потоке, если пинг уже закончен? можно тот же самый использовать;
б) понятно, что в цикле. как это мешает иметь счётчик?


 
Ketmar ©   (2006-11-10 03:13) [9]

>[7] Джо(c) 10-Nov-2006, 03:11
>Ну, так создай специальный класс-менеджер потоков.
всё б тебе классами делать... %-) я вот в DarkEyeProxy безо всяких классов обошёлся -- и ничего. %-)


 
Джо ©   (2006-11-10 03:16) [10]

> [9] Ketmar ©   (10.11.06 03:13)
> всё б тебе классами делать...

А мне — нравится! ;-p


 
image   (2006-11-10 03:18) [11]

>Ну, так создай специальный класс-менеджер потоков. Пускай он их и >создает и считает, при необходимости откладывая создание следующего. В >чем проблема-то?

 Проблема в том, что я только недавно начал разбираться с этими потоками, и пока не знаю как это сделать. Если можете подскжите или дайте ссылочку где можно почитать как его создать этот менеджер потоков.


 
Ketmar ©   (2006-11-10 03:24) [12]

Джо, давай ты. ты посоветовал -- ты и поясняй. %-)


 
Джо ©   (2006-11-10 03:25) [13]

> Если можете подскжите или дайте ссылочку где можно почитать
> как его создать этот менеджер потоков.

Это просто абстрактное понятие.
Смысл в том, что при создании потока увеличиваешь счетчик на 1. При уничтожении, соответственно, на 1 уменьшаешь. И все. Класс тут только для того, чтобы эти манипуляции собрать в одном четком именованном месте кода, он вовсе не обязателен и суть не в нем.


 
image   (2006-11-10 03:33) [14]

<обалдеть. спрячь. а лучше сожги.
<а) на кой фиг определять имя в отдельном потоке, если пинг уже <закончен? можно тот же самый использовать;
<б) понятно, что в цикле. как это мешает иметь счётчик?

а) Да действительно
б) Я же говорю что только начал учиться работе с потоками, поэтому и прошу помощи, если можно хотябы намек на то как его сделать этот счетчик


 
Джо ©   (2006-11-10 03:36) [15]

> если можно хотябы намек на то как его сделать этот счетчик

Счетчик — это переменная целочисленного типа. Увеличить значение счетчика можно процедурой Inc или оператором +. Уменьшить — оператором - или процедурой Dec. В чем же проблема, собственно?


 
Ketmar ©   (2006-11-10 03:37) [16]

а как делаются счётчики? путём объявления переменной с типом, например, Integer. а потом -- Inc() и Dec(). а точнее -- InterlockedIncrement() и InterlockedDecrement(), чтобы совсем уж безопасно было.

логично, что перед созданием нового потока надо проверить значение счётчика, и если возможно, то: счётчик увеличить; поток создать.
если невозможно -- ждать, пока станет возможно.

перед завершением потока оный должен счётчик уменьшить.

всё. для черновой реализации достаточно.


 
image   (2006-11-10 03:40) [17]

>Смысл в том, что при создании потока увеличиваешь счетчик на 1. При >уничтожении, соответственно, на 1 уменьшаешь. И все. Класс тут только >для того, чтобы эти манипуляции собрать в одном четком именованном >месте кода, он вовсе не обязателен и суть не в нем.

Хорошо, с созданием понятно, но тогда как узнать что количество потоков уменьшилось? Насколько я понимаю что они выполняются каждый в своем виртуальном пространстве памяти и знать друг о друге ничего не знают. Как узнать что какой то поток завершился? Есть какая то процедура или функция?


 
Джо ©   (2006-11-10 03:47) [18]

> Насколько я понимаю что они выполняются каждый в своем виртуальном
> пространстве памяти и знать друг о друге ничего не знают.

У класса TThread есть событие OnTerminate.


 
image   (2006-11-10 03:50) [19]

>У класса TThread есть событие OnTerminate

А как его выловить это OnTerminate


 
Джо ©   (2006-11-10 03:50) [20]

Блин, вот костяк. Развивай на свое усмотрение.

type

 TThreadClass = class of TThread;

 TThreadManager = class
 private
   FMaxThreads: Integer;
   FThreadsCount: Integer;
   procedure OnThreadTerminate (Sender: TObject);
 public
   // в конструкторе задаем допустимое кол-во одновременно
   // живущих потоков
   constructor Create (AMaxThreads: Integer); reintroduce;
   // создает поток указанного класса,
   // если их кол-во превышает допустимое, ждет, пока оно уменьшится
   procedure CreateThread (AThreadClass: TThreadClass);
 end;

implementation
uses Forms;

{ TThreadManager }

constructor TThreadManager.Create(AMaxThreads: Integer);
begin
 inherited Create();
 FMaxThreads := AMaxThreads;
 FThreadsCount := 0;
end;

procedure TThreadManager.CreateThread(AThreadClass: TThreadClass);
var
 ANewThread: TThread;
begin
 while FThreadsCount >= FMaxThreads do
   Application.ProcessMessages;

 InterlockedIncrement(FThreadsCount);
 ANewThread := AThreadClass.Create(True);
 ANewThread.OnTerminate := OnThreadTerminate;
 ANewThread.Resume;
end;

procedure TThreadManager.OnThreadTerminate (Sender: TObject);
begin
 InterlockedDecrement(FThreadsCount)
end;

Не думал, что на ночь глядя придется такой ужас писать.


 
image   (2006-11-10 03:53) [21]

>Не думал, что на ночь глядя придется такой ужас писать.

Спасибо всем, а Джо Большое Спасибо!


 
Германн ©   (2006-11-10 04:04) [22]


> Джо Большое Спасибо

Хау! Отныне Джо получил имя "Джо Большое Спасибо"! С новым крещением, Серёга. :-) Племя имеджа тебя не забудет. :-)


 
Джо ©   (2006-11-10 04:07) [23]

> [22] Германн ©   (10.11.06 04:04)
> Хау! Отныне Джо получил имя "Джо Большое Спасибо"! С новым
> крещением, Серёга. :-) Племя имеджа тебя не забудет. :-)

Еду в Папу-Новую Гвинею! :D


 
image   (2006-11-10 04:09) [24]

Шутники однако :-)))


 
Ketmar ©   (2006-11-10 04:14) [25]

>[17] image 10-Nov-2006, 03:40
>они выполняются каждый в своем виртуальном пространстве
неверно понимаешь. путаешь их с процессами.


 
image   (2006-11-10 04:31) [26]

Да, даже в самом первом вопросе перепутал спросил - "Подскажите пожалуйста как создать счетчик запущенных процессов", кажется недоперечитался


 
Сергей М. ©   (2006-11-10 08:35) [27]


> image   (10.11.06 04:31) [26]


Подозреваю, что и потоки те самые тебе не нужны - ф-ции для работы с протоколом ICMP реализуют и асинхронный вариант использования.


 
Anatoly Podgoretsky ©   (2006-11-10 08:42) [28]

> Ketmar  (10.11.2006 04:14:25)  [25]

Как то странно, потоки и неумение создать элементарнейший счетчик, гримасы образования.


 
Anatoly Podgoretsky ©   (2006-11-10 08:45) [29]

> Сергей М.  (10.11.2006 08:35:27)  [27]

Естественно не нужны, это не Инди, а ICS которая изначально не требует никаких потоков, они там вредны. Это асинхронные event driven компоненты - один главный поток и обработчики событий, запустил и продолжай работать, будет событие  - получишь управление.


 
MetalFan ©   (2006-11-10 09:06) [30]

про потоки вроде неплохая статейка
http://forum.vingrad.ru/topic-60076.html


 
image   (2006-11-10 17:01) [31]

> Ketmar  (10.11.2006 04:14:25)  [25]

>Как то странно, потоки и неумение создать элементарнейший счетчик, >гримасы образования.

Ребята, прошу не пинать ногами, ведь  я зашел на форум для начинающих! Ничего плохого в том что люди стремятся к знаниям нет.  А на счет счетчика (менеджера потоков) могу сказать, что самым страшным оказалось слово МЕНЕДЖЕР :-). После прочтения кода (еще раз спасибо Джо), во всем разобрался.


 
Ketmar ©   (2006-11-10 18:17) [32]

>[31] image 10-Nov-2006, 17:01
>Ребята, прошу не пинать ногами, ведь  я зашел на форум для начинающих!
тебя ещё никто не пинал. полазь по форуму немного, увидишь, что такое "пинать". заодно оценишь, как с тобой вежливо обходились %-). я сам удивлён, что всё так прилично. видимо, звёзды к тебе были благосклонны. %-))


 
image   (2006-11-10 19:50) [33]


> Подозреваю, что и потоки те самые тебе не нужны - ф-ции
> для работы с протоколом ICMP реализуют и асинхронный вариант
> использования.


Я тоже подозреваю что при помощи ICMP было бы намного лучше, но ни где не встречал хорошего описания компонентов инди. В инете много примеров, но там так - положите на форму TLabel, TMemo, TButton и скопируйте вот этот кусок кода.Все.Программа готова. Даже иногда и работает. А чего он там инициализирует перед использованием компонента - ни строчки. Хочется разобраться как это работает, а не тупо копировать куски кода.


 
Anatoly Podgoretsky ©   (2006-11-10 19:57) [34]

+-1 это не уровень начинающего, это ниже.


 
Anatoly Podgoretsky ©   (2006-11-10 19:59) [35]

image   (10.11.06 19:50) [33]
С Инди тоже самое - положите на форму компонент и наберите данный код, если он вообще нужен.

С остальным, с разобраться проще - все это в исходных кодах, разбирайся по самое немогу, раз такое желание есть и силы есть разбираться, мы то тут зачем, у тебя все на твоем компьютере.


 
MikePetrichenko ©   (2006-11-10 20:03) [36]


> while FThreadsCount >= FMaxThreads do
>    Application.ProcessMessages;

Всегда поражался, как народ люит глобальные переменны и жрать время процессора :)
Чем вам семафоры не угодили? Или дядюшка Билли их для своего развлечения придумал.

В сад.


 
image   (2006-11-10 20:04) [37]

Ну
> +-1 это не уровень начинающего, это ниже.


Ну сделай те тогда форум для "Начинающие начинать пытаться разобраться в программировании на Дельфи" :-)


 
MikePetrichenko ©   (2006-11-10 20:08) [38]


> Ну сделай те тогда форум для "Начинающие начинать пытаться
> разобраться в программировании на Дельфи" :-)

Дык уже было предложение - "Надмозги".
Голосуем! Кто за?


 
Джо ©   (2006-11-11 04:51) [39]

> [36] MikePetrichenko ©   (10.11.06 20:03)
>
> > while FThreadsCount >= FMaxThreads do
> >    Application.ProcessMessages;
>
> Всегда поражался, как народ люит глобальные переменны и
> жрать время процессора :)
> Чем вам семафоры не угодили? Или дядюшка Билли их для своего
> развлечения придумал.
>
> В сад.

Ну, насчет любви к глобальным переменным — это к дядюшке Борланду, был у него такой грешок.
А насчет "в сад" — это, пожалуйста, к зеркалу. Или даже еще ближе — к коду из [4], который, как видно, взят из рабочего проекта. Да только там ему не место.


 
MikePetrichenko ©   (2006-11-11 16:07) [40]


> Или даже еще ближе — к коду из [4], который, как видно,
> взят из рабочего проекта. Да только там ему не место.

Из АБСОЛЮТНО рабочего.
И почему же ему там не место. Или у вас настолько равиты телепатические способности, что вы можете видеть ВЕСЬ код, откуда выдран данный кусок и предсказать, что же там все-таки делается и почему сделано именно так?



Страницы: 1 2 вся ветка

Текущий архив: 2006.12.03;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.075 c
2-1163538396
Zanci
2006-11-15 00:06
2006.12.03
Про юзов


15-1163591838
PHPDeveloper
2006-11-15 14:57
2006.12.03
InnoSetup


15-1163490325
IntruderLab
2006-11-14 10:45
2006.12.03
Восстановление панели компонентов


2-1163345377
Cr3at0r
2006-11-12 18:29
2006.12.03
FindFirst


8-1145366338
mobila
2006-04-18 17:18
2006.12.03
Копирование на Image2