Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Синхронизация с основным тредом программы не из TThread


Страницы:   1 2 3 4

Дмитрий Белькевич ©   (2011-06-09 15:48:00) 

Добрый день. С синхронизацией из TThread, в целом, все понятно. Как сделать синхронизацию с основным тредом из треда, от которого есть только Idшник: GetCurrentThreadId?


Дмитрий Белькевич   (2011-06-13 12:42:00) [41]

Еще мысль, ведь наверняка можно настройку автоматизировать. Сделать какой-то софт, который всё, что описано в документе http://clck.ru/Ece6будет делать сам. Имея права, само собой.


Дмитрий Белькевич   (2011-06-13 12:40:00) [42]


> Как Вам?


Посмотрел. Ад, конечно. Но - у меня более простой случай - локальное соединение, есть надежда, что в большинстве случаем будет работать сразу.


Loginov Dmitry   (2011-06-12 19:55:00) [43]


> Главное - что бы пользователям систему настраивать, по возможности,
>  не пришлось.


Настройку DCOM никак нельзя назвать легкой. Намного проще написать инструкцию в пару строк о добавлении приложения в список исключений файрволла, чем целую диссертацию о настройках DCOM'а. В простейшем случае настраивать ничего не нужно. Но когда дело дойдет до настройки, тут можно лоб сломать и мозг вывихнуть. Вот один из примеров руководства по настройке DCOM: http://clck.ru/Ece6
Как Вам?


Дмитрий Белькевич   (2011-06-12 19:43:00) [44]


> Засовывать DCOM в службу, имхо, не самое удачное решение.
>  DCOM, как показывает многолетняя практика, не самая удачная
> технология. Почему бы Вам не реализовать службу, к примеру,
>  через Indy компоненты (TIdTCPServer / TIdTCPClient) (вполне
> себе проверенное решение с минимальным количеством подводных
> камней).


Сложности реализации меня не беспокоят - рано или поздно разберусь. Главное - что бы пользователям систему настраивать, по возможности, не пришлось.


Loginov Dmitry   (2011-06-12 18:11:00) [45]


> Уточняю. Вопрос возник по вот этой причине:
>
> http://www.delphimaster.ru/cgi-bin/forum.pl?id=1306751915&n=8
>
> >Пытаюсь вызывать из COM сервера процедуру клиента (Events).
>  Когда вызываю из основного потока (с помощью метода Synchronize)
> - то все происходит нормально - вызов приходит на сторону
> клиента. Когда же вызов идёт из неоснового потока - событие
> клиент не получает.
>


Засовывать DCOM в службу, имхо, не самое удачное решение. DCOM, как показывает многолетняя практика, не самая удачная технология. Почему бы Вам не реализовать службу, к примеру, через Indy компоненты (TIdTCPServer / TIdTCPClient) (вполне себе проверенное решение с минимальным количеством подводных камней).


Loginov Dmitry   (2011-06-12 17:57:00) [46]


> Объявить deprecated проще.


Гораздо проще. Настолько просто, что и Resume досталось. Имхо, незаслуженно.


Loginov Dmitry   (2011-06-12 17:56:00) [47]


> Следовательно, suspend надо сделать таким, чтобы он срабатывал
> только после выхода из критической секции. Но не запрещать
> совсем.


Тогда придется реализацию suspend делать в менеджере памяти. Вряд ли пойдут на это. Да и смысла нет.


sniknik   (2011-06-12 10:55:00) [48]

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


Дмитрий Белькевич   (2011-06-12 10:45:00) [49]

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

Вообще - как связаны сообщения с событиями (Events) COM сервера я так и не нашел, возможно есть какие-то более изящные механизмы доступа к событиям сервера, чем Synchronize.

В любом случае - спасибо всем ответившим.


sniknik   (2011-06-12 01:38:00) [50]

>> В неосновном потоке, конечно же, цикла выборки сообщений нет.

> То есть - мне нужен аналог Synchronize для потоков, к которым я не могу обратиться как к TThread'у.

?????????????????????

синхронизация потоков с циклом выборки и рядом не лежала...


Дмитрий Белькевич   (2011-06-12 01:10:00) [51]


> Автору стоило бы более подробно раскрыть суть проблемы.


Уточняю. Вопрос возник по вот этой причине:

http://www.delphimaster.ru/cgi-bin/forum.pl?id=1306751915&n=8

>Пытаюсь вызывать из COM сервера процедуру клиента (Events). Когда вызываю из основного потока (с помощью метода Synchronize) - то все происходит нормально - вызов приходит на сторону клиента. Когда же вызов идёт из неоснового потока - событие клиент не получает.

>DiamondShark ©   (01.06.11 11:57) [1]
>В неосновном потоке, конечно же, цикла выборки сообщений нет.

То есть - мне нужен аналог Synchronize для потоков, к которым я не могу обратиться как к TThread'у.

Похоже, что TThread.Synchronize(nil, SomeMethod) делает то, что нужно.


Eraser   (2011-06-11 03:42:00) [52]

> [12] jack128_   (10.06.11 21:39)

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


Германн   (2011-06-11 01:50:00) [53]


> Следовательно, suspend надо сделать таким

Объявить deprecated проще.
Ведь сколько уже deprecated было в Дельфи.


Юрий Зотов   (2011-06-11 00:47:00) [54]

Следовательно, suspend надо сделать таким, чтобы он срабатывал только после выхода из критической секции. Но не запрещать совсем.


Loginov Dmitry   (2011-06-11 00:34:00) [55]


> Какие?


Менеджер памяти в многопоточном приложении синхронизирует операции распределения памяти. Для D7 - с помощью обычной критической секции, в более новых версиях используются другие способы синхронизации (более выгодные в плане производительности). В любом случае есть синхронизация, которая выглядит приблизительно так:
CriticalSection.Enter;
try
 Код распределения памяти
finally
 CriticalSection.Leave;
end;


Представим себе следующий сценарий:
1. Поток "А" запросил выделение памяти. Сработал CriticalSection.Enter. Начал выполняться блок "Код распределения памяти".
2. Поток "В" в этот момент вызвал Suspend потоку "А".
3. Поток "В" запросил выделение памяти. Сработал CriticalSection.Enter. Однако к этому моменту поток "А" уже захватил критическую секцию CriticalSection.

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

Именно по этим причинам Suspended считается deprecated. Отладка многопоточного приложения в Delphi зачастую виснет, судя по всему, по аналогичным причинам.

На королевстве имеется замечательная статья, в которой все сказанное описано более подробно, с примерами (или с ссылками на примеры).


Юрий Зотов   (2011-06-10 23:40:00) [56]

> И deprecated оно стало не просто так, тому есть веские причины.

Какие?

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


jack128_   (2011-06-10 21:39:00) [57]


> Synchronize - прямой путь к дэдлокам и не очевидной логике
> работы программы.

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


Loginov Dmitry   (2011-06-10 21:35:00) [58]


> Вообще, лучше, конечно, таких ситуаций изьегать (может быть,
>  стоит пересмотреть логику программы?).
>
> Но если уж очень надо, то можно попробовать так:
>
> 1. Найти поток по его ID.
> 2. Сделать ему suspend.
> 3. Синхронизироваться с главным потоком.
> 4. Сделать ему resume.


Юрий, suspend является deprecated начиная с D2010. Насколько я знаю, в некоторых из популярных языков программирования ситуация аналогичная (насколько помню и Java и .NET (возможно за исключением последних версий) в их числе). И deprecated оно стало не просто так, тому есть веские причины.


Loginov Dmitry   (2011-06-10 21:28:00) [59]


> Вопрос не раскрыт.


+1

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


Dimka Maslov   (2011-06-10 18:48:00) [60]

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


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо