Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> PostMessage, одновременно из разных потоков 
V
    Опции темы
Steel
Дата 21.1.2007, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 14.5.2006
Где: Россия, Саратов

Репутация: нет
Всего: нет



Цель такая : хочу сихронизировать запись в 1 файл лога сообщений из нескольких потоков. 
Для этого посылаю из этих потоков указатель на сообщения с помощью PostMessage. 
Сообщения посылаются главной и единственной форме приложения, в классе которой сидит прцедура их обрабатывающая.
Потоки создаются TidTCPServer.
Идея такая, что даже если два или несколько сообщений одного типа отправятся одновременно то они корректно встанут в очередь и 
последовательно обработаются моей процедурой обработки.

Вопрос : Я прав? Или тут есть какие-то нюансы, которых я не знаю или проблемы, которых не вижу?
PM MAIL   Вверх
MetalFan
Дата 21.1.2007, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



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



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
W4FhLF
Дата 21.1.2007, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 6
Всего: 121



Ну PostMessage имеет очередь, должно обрабатывать корректно.


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Romikgy
Дата 21.1.2007, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



Цитата(Steel @  21.1.2007,  12:45 Найти цитируемый пост)
из этих потоков указатель на сообщения с помощью PostMessage. 

а доступ к данным под указателем как разруливать будешь?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Steel
Дата 21.1.2007, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 14.5.2006
Где: Россия, Саратов

Репутация: нет
Всего: нет



Я планировал примерно так

Код

var
     pS        : ^String;
     LogList : TStringList;

procedure SendMsg;
begin
  New(pS);
  pS^:='Сообщение';
  PostMessage(Handle,WM_USER+2,Integer(pS),LParam);
end;

procedure GetMsg(var Msg:TMessage);
var
     pS1:^String;
begin
  pS1:=Pointer(Msg.wParam);
  LogList.Add(pS1^);
  Dispose(pS1);
end;


Нужно делать что-то еще?

Это сообщение отредактировал(а) Girder - 22.1.2007, 15:27
PM MAIL   Вверх
Romikgy
Дата 21.1.2007, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



Цитата(Steel @  21.1.2007,  16:03 Найти цитируемый пост)
var
     pS        : ^String;
     LogList : TStringList;

procedure SendMsg;
begin
  New(pS);
  pS^:='Сообщение';
  PostMessage(Handle,WM_USER+2,Integer(pS),LParam);
end;

procedure GetMsg(var Msg:TMessage);
var
     pS1:^String;
begin
  pS1:=Pointer(Msg.wParam);
  LogList.Add(pS1^);
  Dispose(pS1);
end;


Цитата(Steel @  21.1.2007,  16:03 Найти цитируемый пост)
 LogList.Add(pS1^);

это обращение к переменой 
Цитата(Steel @  21.1.2007,  16:03 Найти цитируемый пост)
pS^:='Сообщение';

и если оно из потока, то оно не защещено, хотя при чтении это не смертельно , хотя и не хорошо



--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Steel
Дата 22.1.2007, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 14.5.2006
Где: Россия, Саратов

Репутация: нет
Всего: нет



Я так понимаю что New(pS) каждый раз выделяет память под новую строку, адрес которой никто кроме обрабатывающей процедуры не узнает, а стало быть никогда ее не прочитает и не узнает. Поэтому, т.к. обрабатывающая процедура процедура выполняется в основном потоке данный код будет равносилен добавлению в СтрингЛист обычной глобальной переменной. Как будто бы и небыло никаких потоков. Я не прав ?


Это сообщение отредактировал(а) Steel - 22.1.2007, 09:12
PM MAIL   Вверх
Romikgy
Дата 22.1.2007, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



мой те совет ,
попробуй передавать строки из потоке через глобальные атомы  smile  имхо безопаснее будет


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
dumb
Дата 22.1.2007, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 13
Всего: 158



в пределах одного приложения таки можно не извращаться, так как менеждер один и тот же.
Steel, делай как задумал.
PM MAIL   Вверх
MetalFan
Дата 22.1.2007, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



несколько замечаний по исходному коду
1) кто так память под string выделяет?! может я и не прав, но имхо объявление ^String.... это изврат) выход: использовать PChar;
2) pS - глобальная переменная, потоконебезопасна.
что будет если при выполнении процедуры SendMsg в одном потоке управление после New(pS) перейдет к другому потоку??
выход: использовать локальную переменную-указатель.
3) PostMessage не гарантирует обработку сообщения. в случае ошибки в главном(обрабатывающем) потоке получишь утечку памяти. выход: использовать другой способ синхронизации между потоками. например посмотри ДНК TThread.Synchronize.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
dumb
Дата 22.1.2007, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 13
Всего: 158



Цитата(MetalFan @  22.1.2007,  13:05 Найти цитируемый пост)
Synchronize

это из другой оперы. одно дело - нотификация, другое - синхронизация.

Цитата(MetalFan @  22.1.2007,  13:05 Найти цитируемый пост)
PostMessage не гарантирует обработку сообщения

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

imho излишняя параноидальность в программировании - зло такое же, как и недостаточная внимательность. если уж совсем замучают мысли об этих утечках, можно и "уборщик" сделать... smile
PM MAIL   Вверх
MetalFan
Дата 22.1.2007, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(dumb @  22.1.2007,  13:31 Найти цитируемый пост)
одно дело - нотификация, другое - синхронизация.

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

Цитата(dumb @  22.1.2007,  13:31 Найти цитируемый пост)
...излишняя параноидальность в программировании...

излишняя безалаберность в программировании приводит к появлению таких глюков (трудноуловимые AV например), которые замучаешься потом отлавливать. 
так зачем усложнять себе будущую жизнь, не лучше ли изначально все нормально сделать? конечно 100% безглючный код практически нереально сходу создать, но стремиться то к этому надо!





--------------------
There are always someone smarter than you...
PM MAIL   Вверх
dumb
Дата 22.1.2007, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 13
Всего: 158



Цитата(MetalFan @  22.1.2007,  13:50 Найти цитируемый пост)
другое дело, когд один кусок кода память выделяет, другой освобождает. это ну совсем не есть хорошо. опять же имхо.

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

Цитата(MetalFan @  22.1.2007,  13:50 Найти цитируемый пост)
излишняя безалаберность в программировании приводит к появлению таких глюков

предполагать маловероятным переполнение очереди сообщений - не думаю, что это можно назвать безалаберностью. а осознанные допущения - суровая жизненная необходимость. иначе кушать будет нечего - будешь голодным "if'ы расставлять"... smile
PM MAIL   Вверх
Steel
Дата 22.1.2007, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 14.5.2006
Где: Россия, Саратов

Репутация: нет
Всего: нет



Как вы наверное заметили я не слишком силен в потоках.
Поэтому. Если не трудно. Было бы неплохо получить пример обработчика OnExecute компонента TIdTCPServer, который что-либо выполняет в основном потоке.

PS использую Indy9
PM MAIL   Вверх
Steel
Дата 25.1.2007, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 14.5.2006
Где: Россия, Саратов

Репутация: нет
Всего: нет



Спасибо всем кто мне помогал. То что хотел - реализовал. Насколько успешно - покажет время.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0918 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.