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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Синхронизация потоков, Как правильнее? 
:(
    Опции темы
danilsl
Дата 21.3.2007, 02:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Здравствуйте.
В моём приложении должно работать несколько одинаковых потоков. Эти потоки не обращаются к визуальным компонентам VCL. Все они должны будут вызывать одну и ту же функцию ещё одного потока, например, главной нити приложения. Этот поток тоже не использует визуальных компонентов. Можно ли их синхронизировать функцией synchrinize() или более корректно будет использовать критические секции, наподобие такого:
Код

var
  CriticalSection:TRtlCriticalSection;
begin
  ...
  InitializeCriticalSection(CriticalSection);
  ...//Вызов функции основного потока
  DeleteCriticalSection(CriticalSection);
end;

Во всех книжках, что я видел, synchrinize() описывается именно в применении к визуальным компонентам и ни слова не сказано про синхронизацию потоков, не использующих VCL.
PM MAIL   Вверх
dumb
Дата 21.3.2007, 02:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


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

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



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

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

либо штудировать статьи по много-поточности до полного просветления...

ps. кстати, пример кода неправильный - на месте твоих InitializeCriticalSection-DeleteCriticalSection должны быть EnterCriticalSection - LeaveCriticalSection. а указанные тобой - это инициализация и удаление, т.е. выполняются один раз.
PM MAIL   Вверх
Alexeis
Дата 21.3.2007, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(danilsl @  21.3.2007,  02:07 Найти цитируемый пост)
Во всех книжках, что я видел, synchrinize() описывается именно в применении к визуальным компонентам и ни слова не сказано про синхронизацию потоков, не использующих VCL. 

А в этой есть и то и другое http://forum.vingrad.ru/index.php?showtopi...76&view=all  smile 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
danilsl
Дата 22.3.2007, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ну значит вот суть задачи:
Пишу прогу для управления компьютерным клубом. Не то чтобы шеф жадный и не хочет ничего покупать, просто имеющееся за разумную плату не устраивает. И в первую очередь меня. Так как админить всё это мне. Прога будет состоять из 3-х частей. 1-я это сервер. Будет выполнен в виде службы. Никаких гуи и командных строк для него не предвидится. Будет работать на отдельном сервере, доступа к которому ни у кого не будет. Это для того, чтобы не изобретать велосипед с шифрованием статистики и контролем её подмены. Две другие части будут присоединяться по сети. Это будут программа для кассира и прога, работающая на клиентском компе, блокирующая комп по истечении оплаченного сеанса. Какого-то конкретного кода ещё нет. Пока обдумываю структуру проги, пишу на бумажке чего от неё нада да блок-схемы рисую.
Сложность вот в чём. Серверная часть программы создаст два серверных сокета, один для админов, другой для клиентов. На каждое подключение будет создан отдельный поток. Кстати, в клиентской части тоже будет возможность включения времени, например по клубной карте. И вот к примеру ситуация: На комп садится клиент с картой и покупает себе время. Это обрабатывает клиентский поток сервера. В это же время админ, не знающий что оплата этого компа уже в процессе, тоже пытается завести сеанс на этом же компе. Этот запрос параллельно обрабатывается админским потоком. В итоге, клиентский и админский потоки вызывают одну и ту же функцию, формирующую сеанс. Эта функция, в двух разных потоках начинает обращаться к одной структуре данных. Вот эту ситуацию мне и надо предотвратить.
Структура, к которой будут обращаться потоки будет выглядеть примерно так:
Код

  TComputer = class
  private
    FGroup: word;
    FUser: word;
    FBoughtTraffic: long; //В байтах
    FTrafficUse: long;
    FPrice: word; // В копейках
    FOrderList: TList;
    FClientSocket: Pointer;//Сюда будет загоняться указатель на клиентский поток, общающийся с компом
                                        //Это же признак включенности компа для админа.
  public
    property Group read FGroup write FGroup;
    property User read FUser;
    property BoughtTraffic read FBoughtTraffic;
    property TrafficUse read FTrafficUse;
    property Price read FPrice;
    constructor Create;
    destructor Destroy;
    function CreateOrder(StartTime, EndTime:TDateTime; SeansType:word; user:word):boolean;
    procedure RemoveOrder(StartTime:TDateTime);
    procedure ActivateOrder(StartTime:TDateTime);
  end;

По сути, из двух разных потоков будет одновременно вызвана функция CreateOrder. Её реализации ещё нет. Делать она будет примерно следующее: Просмотр уже имеющихся предоплаченых сеансов, и если новый сеанс не пересекается с уже имеющимися, то расчёт стоимости в зависимости от типа сеанса, группы компа и юзера. И собственно добавление этого сеанса. Соответственно на выходе - создан сеанс или нет.
И вот мне нужно, чтобы для каждого компа гарантированно выполнялось не более одного экземпляра этой функции.
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.0786 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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