Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.11.2010, 15:18   #1
Vadik(R)
Пользователь
 
Регистрация: 10.03.2008
Сообщений: 68
По умолчанию Последовательная обработка событий

Люди, помогите с проблемой. Допустим есть какое-то событие Event, которое происходит с неизвестным интервалом времени, и есть обработчик этого события - OnEvent. В который передаются данные, например, строка. Вопрос в следующем: событие может возникать очень часто и обработчик события, возможно, будет неуспевать обрабатывать переданные ему данные, как тут же запустится обработчик второго события. По идее, предотвратить это легко, например, семафором. То есть, тогда обработчик следующего события не запустится, пока не завершиться текущий. Но есть еще проблемка: нужно, чтобы события обрабатывались в той последовательности, в которой они появлялись. То есть, произошли собития Event с данными Data1, Event с данными Data2 и Event с данными Data3. Если использовать семафор, то вначале будет обрабатываться событие Event с данными Data1, а остальные будут ждать семафора. Но когда его обработка закончится, с равной вероятностью может выполняться как обработчик события Event с данными Data2, так и обработчик события Event с данными Data3. Нужно, чтобы они делались последовательно в том порядке, в котором они возникали. То есть, шла обработка вначале Event с данными Data1, потом Event с данными Data2 и потом Event с данными Data3. Помогите, как этого добиться?
Vadik(R) вне форума Ответить с цитированием
Старый 05.11.2010, 15:25   #2
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Да как нефиг делать. Для этого умные люди придумали очереди. Для твоего примера со строкой это будет массив строк, только его надо правильно организовать. А именно по принципу - Первый пришел-Первый ушел. Гугли LIFO и FIFO. При возникновения события ты пихаешь строку в очередь и передаешь управление обработчику. Обработчик берет только то событие которое первым стоит на очереди и никакое другое и все, наши победили.
А вот это:
Цитата:
и обработчик события, возможно, будет неуспевать обрабатывать переданные ему данные
не есть хорошо. Чего же ты такого там разбираешь, что аж комп за тобой не успевает?
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 05.11.2010, 15:37   #3
Vadik(R)
Пользователь
 
Регистрация: 10.03.2008
Сообщений: 68
По умолчанию

События могут возникать быстро, а обрабатываться - долго. Про очереди была идейка, просто опять, если реализовывать их рукаим, то в очередь могут встать первая, потом третья, а потом вторая строка.
А так погуглю эти штуки, если будут вопросы - вернусь
Vadik(R) вне форума Ответить с цитированием
Старый 05.11.2010, 15:46   #4
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Сообщение от Vadik(R) Посмотреть сообщение
События могут возникать быстро, а обрабатываться - долго. Про очереди была идейка, просто опять, если реализовывать их рукаим, то в очередь могут встать первая, потом третья, а потом вторая строка.
Если строка будет помещаться в очередь непосредственно перед обработчиком события, то такое невозможно. Хотя не знаю, что там за вопрос и как ты его там понял . Если можно определить какая строка первая, а какая пятая, то проблем с очередью обработки возникать не должно...
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 05.11.2010, 16:52   #5
Vadik(R)
Пользователь
 
Регистрация: 10.03.2008
Сообщений: 68
По умолчанию

Есть Someobject с событием Event.
Тогда код будет выглядеть примерно так:
Код:
//Глобальные переменные
var
  queue: array [1..1000] of ansistring;
  n1, n2: integer;

procedure SomeobjectEvent(str: ansistring);
begin
  inc(n2);
  queue[n2] := str;
  ...{семефор}
  inc(n1);
  ... {Обработка строки queue[n1]}
end;
И вот тут и проявляется этот минус. Поскольку, строка с индексом n1 - не обязательно та, которая должна обрабатываться (поскольку, могло получиться так queue[1] = str1, queue[2] = str3, queue[3] = str2). А имея весь массив строк - тоже нельзя определить очередность строк. Поэтому, проблема в том, как записать в очередь строки в нужном порядке.
Vadik(R) вне форума Ответить с цитированием
Старый 05.11.2010, 21:36   #6
Vadik(R)
Пользователь
 
Регистрация: 10.03.2008
Сообщений: 68
По умолчанию

Хм, люди. Есть вопрос, который возможно полностью решит мою проблему. Я думал в Delphi стандартные обработчики одних и тех же событий обрабатываются в разных потоках.
Для этой цели я решил сделать эксперимент, а именно: Установить таймер на 1 мсек и написать код:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  n: integer;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  n := 0;
  Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  f: textfile;
begin
  if n > 100000 then Timer1.Enabled := False;
  inc(n);
  assignfile(f, '1.txt');
  append(f);
  writeln(f, n);
  closefile(f);
end;

end.
И, по идее, если обработчики выполняются в разных потоках - успела бы возникнуть ошибка, что есть попытка открыть файл, который открыт уже другим обработчиком. На 100000 событий уж наверняка бы появилась ошибка. Но каково же было моё удивление, когда я открыл файл и увидел в нём _последовательно_ идущие числа. То есть, это говорит о том, что делфи сама во-первых, ставит события в очередь правильно, и, во-вторых, пока не завершиться обработка текущего события (onTimer), он следующее выполнять не будет. Собственно, хотел узнать у вас: действительно ли это так?
И справедливо ли это для обработчика procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);??
Просто я в обработчике делаю довольно долгую обработку полученной строки O(n^2) и пишу её в файл. Я не боялся, что будет двойное открытие файла для записи, эту проблему я знал как уладить. Я боялся, что запись в файл будет происходит не в том порядке, в котором приходит текст (могла прийти длинная, а потом короткая строка) (рассуждения из рисунка http://s011.radikal.ru/i315/1011/6d/71e6a15a0117.jpg). Выходит, мне не о чем беспокоится?
Vadik(R) вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обработка событий meganom Общие вопросы Delphi 5 01.09.2010 19:41
Обработка событий из консоли D_E_N Общие вопросы Delphi 2 24.07.2009 16:50
Обработка событий в Delphi SlavaSH Компоненты Delphi 19 30.03.2009 11:00
Обработка событий в C++ Builder BychkovVV Помощь студентам 3 02.03.2009 01:48