Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2018.03.04;
Скачать: [xml.tar.bz2];

Вниз

Создание потоков   Найти похожие ветки 

 
sniknik ©   (2016-03-16 18:37) [40]

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

— Эх, эх... — сказал гость, морщась.
— А  вам, что же, мои  стихи не  нравятся?  — с любопытством  спросил Иван.
— Ужасно не нравятся.
— А вы какие читали?
— Никаких я ваших стихов не читал! — нервно воскликнул посетитель.
— А как же вы говорите?
— Ну, что  ж тут  такого, — ответил  гость, — как будто я  других не читал? Впрочем...  разве что чудо? Хорошо,  я готов  принять на веру. Хороши ваши стихи, скажите сами?
— Чудовищны! — вдруг смело и откровенно произнес Иван.
— Не пишите больше! — попросил пришедший умоляюще.
— Обещаю и клянусь! — торжественно произнес Иван.


 
Макака   (2016-03-16 19:09) [41]

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


 
Rouse_ ©   (2016-03-16 19:16) [42]

Ты код свой показать целиком можешь? А то сиди тут гадай на кофейной гуще в какую лужу ты вступил


 
sniknik ©   (2016-03-17 08:40) [43]

а как же тогда интрига? долгие псевдоинтелектуальные вопросы ни о чем? не, код не нужен.

- А Скрипач не нужен, родной. Он только лишнее топливо жрёт.


 
Юрий Зотов ©   (2016-03-17 10:11) [44]

> до момента "приехали" виснет приложение

Оно не виснет. Оно ждет завершения всех потоков. Вы же сами вызвали WaitForMultipleObjects - вот оно и ждет.


 
Юрий Зотов ©   (2016-03-17 10:22) [45]

А чтобы не "висло", можно сделать так - вместо INFINITE поставить разумный интервал (например, 1 сек) и вызывать WaitForMultipleObjects в цикле:

while WaitForMultipleObjects(4, @Handles[0], true, 1000) = WAIT_TIMEOUT do
 Application.ProcessMessages;


 
sniknik ©   (2016-03-17 10:57) [46]

> while WaitForMultipleObjects(4, @Handles[0], true, 1000) = WAIT_TIMEOUT do
>  Application.ProcessMessages;
???
не учите плохому... он же именно так и "собезьяничает".

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


 
Юрий Зотов ©   (2016-03-17 11:29) [47]

> sniknik ©   (17.03.16 10:57) [46]

Не вижу ничего плохого. Это не таймер, который бессмысленно расходует процессорное время, а нормальное ожидание завершения всех задач.

> если появилась нужда в подобном коде, то смысл вообще в потоках?
> поток нужен если требуется параллельно что-то делать,

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

Похоже на задачу массового обслуживания: в магазине есть N продавцов и магазин не должен закрываться, если хотя бы один продавец еще занят.

Пример из реальной практики. Невизуальное приложение обрабатывает информацию от нескольких терминалов сбора данных. Главный поток слушает подключение терминала и, обнаружив его, порождает поток обработки данных от этого терминала, а сам продолжает прослушку.

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

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


 
эндсоувот ©   (2016-03-17 11:36) [48]

а нормальное ожидание завершения всех задач.

нормальное будет через MsgWaitForMultipleObjects

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

Если ждать - потоки не нужны.
Если потоки нужны, то их не надо ждать.
Расскажите им про хендл нужного окна и потоки сами скажут когда они завершили работу.


 
Юрий Зотов ©   (2016-03-17 11:46) [49]

> через MsgWaitForMultipleObjects

Согласен, но цикл и ProcessMessages при этом все равно останутся.

> хендл нужного окна

1. Окна может и не быть.
2. Потребуется синхронизация.


 
эндсоувот ©   (2016-03-17 12:01) [50]

пример разумного использования потоков без ожиданий синхронайзов и прочих колхозов:

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

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

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

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


 
sniknik ©   (2016-03-17 12:14) [51]

> 1. Окна может и не быть.
но управляющий процесс/поток то есть? т.что PostTreadMessage в общий канал управления
> а сам продолжает прослушку.
здесь и поймает

> 2. Потребуется синхронизация.
зачем? простой счетчик работающих потоков, инкримент перед стартом, декремент по сообщению о завершении из самого потока.

> Тогда, получив команду на завершение
либо завершается если счетчик работающих = 0, либо взводит "флаг" на завершение по которому
> перестает порождать новые потоки
и завершается по достижению счетчиком нуля.

никакой синхронизации, и ожиданий не требуется, все в стиле "событие -> реакция".


 
Юрий Зотов ©   (2016-03-17 12:25) [52]

> и завершается по достижению счетчиком нуля.

Вот именно ЭТО и означает: ЖДАТЬ обнуления счетчика.


 
эндсоувот ©   (2016-03-17 12:29) [53]

"ждать" понятие растяжимое.

юзер ничего не делающий и глазеющий на форму тоже как бы "ждет".

а вопрос лишь в том, что в это время происходит "под формой"

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

а если цикла нет, то у нас доступно все


 
sniknik ©   (2016-03-17 12:35) [54]

> Вот именно ЭТО и означает: ЖДАТЬ обнуления счетчика.
нет, т.к. никаких функций ожиданий/псевдоожиданий([45]) в коде нет, есть обработчик событий с реакцией на них.
разница однако...

> в магазине есть N продавцов и магазин не должен закрываться, если хотя бы один продавец еще занят.
по этой, же аналогии:
ожидание: охранник закрывающий магазин "втыкает" на продавцов, ждет в общем (весело если кассы сильно разнесены).
событие: выключение последней кассы оповещает охранника (звонок в магазине), который может заниматься чем угодно вместо "втыкания", но по звонку идет и закрывает магазин.


 
Макака   (2016-03-17 17:38) [55]

Смысл в том, что когда мы нажимаем на кнопку расчёты появляется полупрозрачная панелька с гифкой и надписью "ожидайте"(чтобы гифка не зависала, нужно чтобы форма не висла), далее запускаются 4 потока и производятся расчёты, после их завершения обновляются компоненты на форме и панель прячется.
Вчера реализовал по "колхозному" через таймер.
Сегодня буду разбираться что выше написано, понять как нужно сделать (без колхоза).


 
Inovet ©   (2016-03-17 20:37) [56]

> [55] Макака   (17.03.16 17:38)
> далее запускаются 4 потока и производятся расчёты, после
> их завершения обновляются

Тогда надо
1. Отдавать потокам (нитям) порции небольшого размера, менее вся_порция/число_потоков.
2. В вызывающей нити распределять остатки, в разумных пределах, чтобы не уйти в бесконечность.;)

И тогда следует юзать
WaitForMultipleObjects
с анализом - кто там завершился и подкидкой ему новой порции.


 
Eraser ©   (2016-03-17 21:08) [57]

Ждать завершения потока/ов нужно в OnTerminate, который выполняется в контексте главного потока приложения.

Никакие таймеры и циклы ожидания тут не нужны, это лишнее для данной задачи. Лезть со своими "ожиданиями" в цикл выполнения основного потока допустимо только в случае крайней необходимости.


 
NoUser ©   (2016-03-18 00:13) [58]

>  Лезть со своими "ожиданиями" в цикл выполнения основного
> потока допустимо только в случае крайней необходимости.

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

Поэтому [45] учитывая [55] для ТС самое оно.


> [54] > событие: выключение последней кассы

а кто определит, что она последняя?


 
sniknik ©   (2016-03-18 01:01) [59]

сама и определит, ее же закрывают, снимают z-отчет. что само по себе событие... выше про счетчик почитай.
не нужно плодить сущности.



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

Форум: "Начинающим";
Текущий архив: 2018.03.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.004 c
2-1458222695
Новичок
2016-03-17 16:51
2018.03.04
Юниты


15-1470691802
Юрий
2016-08-09 00:30
2018.03.04
С днем рождения ! 9 августа 2016 вторник


2-1457077794
Dmk
2016-03-04 10:49
2018.03.04
Биты


15-1470376172
p
2016-08-05 08:49
2018.03.04
Road Map эмбаркадеро


2-1456672132
Макака
2016-02-28 18:08
2018.03.04
Сортировка TList





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский