Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 30.08.2013, 14:33
babay89 babay89 вне форума
Прохожий
 
Регистрация: 20.09.2011
Сообщения: 39
Репутация: -2571
По умолчанию Критическая секция

Здравствуйте! Образовался такой вопрос: Как взять данные из memo, которые ещё не были взяты потоком. Наверное непонятно.
У меня есть Memo, в котором хранятся данные. Как загрузить в поток строку, которую ещё не взял один из потоков. Я понимаю, что сдесь нужна критическая секция, но как использовать её в связке с memo не пойму.
В memo есть такие строки:
чавыа
ывфыв
укцук
выаывп
Нужно что бы каждый поток взял по одной строке, а не все потоке одну строку.

Последний раз редактировалось babay89, 30.08.2013 в 14:47.
Ответить с цитированием
  #2  
Старый 30.08.2013, 15:25
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

как вариант:
Код:
interface

uses
  SyncObjs,
...
implementation

var
  CriticalSection: TCriticalSection;

function GetMemo: String;
begin
  CriticalSection.Enter;
  if Form1.Memo1.Lines.Count>0 then
  begin
    Result:=Form1.Memo1.Lines[0];
    Form1.Memo1.Lines.Delete(0);
  end else Result:='';
  CriticalSection.Leave;
end;
...
initialization
  CriticalSection:=TCriticalSection.Create;

finalization
  CriticalSection.Free;

из потоков вызывай GetMemo.

если удалять нельзя, то завести текущий номер строки и в блоке Enter-Leave возвращать строку по номеру и делать номеру инкремент.
__________________
Пишу программы за еду.
__________________

Последний раз редактировалось NumLock, 30.08.2013 в 15:27.
Ответить с цитированием
  #3  
Старый 30.08.2013, 16:52
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark сейчас на форуме
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,907
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Немного добавлю в код:
Код:
interface

uses
  SyncObjs,
...
implementation

var
  CriticalSection: TCriticalSection;

function GetMemo: String;
begin
  CriticalSection.Enter;
  try  //<------------------------------------------------
    if Form1.Memo1.Lines.Count>0 then
    begin
      Result:=Form1.Memo1.Lines[0];
      Form1.Memo1.Lines.Delete(0);
    end else Result:='';
  finally
    CriticalSection.Leave;
  end;
end;
...
initialization
  CriticalSection:=TCriticalSection.Create;

finalization
  CriticalSection.Free;
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #4  
Старый 01.09.2013, 15:44
babay89 babay89 вне форума
Прохожий
 
Регистрация: 20.09.2011
Сообщения: 39
Репутация: -2571
По умолчанию

Цитата:
Сообщение от NumLock
если удалять нельзя, то завести текущий номер строки и в блоке Enter-Leave возвращать строку по номеру и делать номеру инкремент.
Извините, пожалуйста, но я ни чего не понял. Можно подробнее?
Хоть и первая функция подходит, но она удаляет ровно столько строк, сколько потоков, а нужно что бы удалялось, пока в мемо не будет строк.

Последний раз редактировалось babay89, 01.09.2013 в 16:14.
Ответить с цитированием
  #5  
Старый 01.09.2013, 16:33
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

ну так если создать столько потоков сколько строк в Мемо, то все будет хорошо.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #6  
Старый 01.09.2013, 16:38
babay89 babay89 вне форума
Прохожий
 
Регистрация: 20.09.2011
Сообщения: 39
Репутация: -2571
По умолчанию

Цитата:
Сообщение от NumLock
ну так если создать столько потоков сколько строк в Мемо, то все будет хорошо.
Нет, так не пойдет! Пользователь сам задает кол-во потоков. Нужно как-то в цикл эт запихнуть что ли...
Да 3-4 тысячи потоков не есть гуд.

Последний раз редактировалось babay89, 01.09.2013 в 17:07.
Ответить с цитированием
  #7  
Старый 01.09.2013, 17:51
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

ну тогда цикл создания потоков от 0 до кол-ва строк в Мемо - 1, с ограничением количества потоков семафором. либо цикл с удалением строк из Мемо пока не кончатся. вариантов много...
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #8  
Старый 01.09.2013, 17:53
babay89 babay89 вне форума
Прохожий
 
Регистрация: 20.09.2011
Сообщения: 39
Репутация: -2571
По умолчанию

Цитата:
Сообщение от NumLock
цикл с удалением строк из Мемо пока не кончатся. вариантов много...
Подскажите, как реализовать?
Ответить с цитированием
  #9  
Старый 01.09.2013, 18:00
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Код:
  while Memo1.Lines.Count>0 do
    with TThread.Create...
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #10  
Старый 01.09.2013, 18:14
babay89 babay89 вне форума
Прохожий
 
Регистрация: 20.09.2011
Сообщения: 39
Репутация: -2571
По умолчанию

Цитата:
Сообщение от NumLock
Код:
  while Memo1.Lines.Count>0 do
    with TThread.Create...
но так будут создаваться потоки. Мне это не надо. Я создаю потоки и заношу их в массив потоков. Нужно что бы, например, 10 потоков брали разные строки из мемо и выполняли с ними действия.
Ответить с цитированием
  #11  
Старый 01.09.2013, 18:36
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

ну так см. 2-ое сообщение.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #12  
Старый 01.09.2013, 22:02
babay89 babay89 вне форума
Прохожий
 
Регистрация: 20.09.2011
Сообщения: 39
Репутация: -2571
По умолчанию

Цитата:
Сообщение от NumLock
ну так см. 2-ое сообщение.
Не то. Там берется ровно столько строк, сколько потоков. А нужно что бы потоки брали строки пока они не кончятся в мемо.
Ответить с цитированием
  #13  
Старый 02.09.2013, 08:49
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

там вообще нет потоков

1. переписать функцию как:
Код:
function GetMemo(var S: String): Boolean;
возвращает true если строка вернулась, т.е. была в Мемо. при этом из Мемо удаляет
2. поток проверяет результат функции и если вернет false прекращается
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #14  
Старый 02.09.2013, 09:10
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,088
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от babay89
Не то. Там берется ровно столько строк, сколько потоков. А нужно что бы потоки брали строки пока они не кончятся в мемо.

Ну тебе же выше написали как.
Делаешь метод, который возвращает очередную строку из Memo или пустую строку, если строки кончились. Внутри метода надо работать через CriticalSection. Каждый поток для получения данных "дергает" этот метод, если вернулась пустая строка, то завершается (ну или ждет пока не появяться новые данные). Сам метод, в зависимотсти от того, что нужно делать, либо удаляев взятые строки, либо просто запоминает последнюю взятую.

Вот _пример_ второго варианта:
Код:
type
  TMyForm = class(TForm)
    Memo1 : TMemo;
  ...
  private
    FLastProcessedLine : Integer; // поставить в -1 в конструкторе или в OnCreate
  public
    function GetNextLine : String;
  end;

var
  csGetNewLine : TCriticalSection;
...

function TMyForm.GetNextLine : String;
begin
  csGetNewLine.Enter
  Try
    If Memo1.Lines.Count-1 > FLastProcessedLine
      Then
        Begin
          Inc(FLastProcessedLine);
          Result := Memo1.Lines[FLastProcessedLine];
        End
      Else Result := '';
  Finally
    csGetNewLine.Leave;
  End;
end;

...

initialization
  csGetNewLine := TCriticalSection.Create;

finalization
  csGetNewLine.Free;

end.

Как-то так.
Ответить с цитированием
  #15  
Старый 02.09.2013, 12:26
babay89 babay89 вне форума
Прохожий
 
Регистрация: 20.09.2011
Сообщения: 39
Репутация: -2571
По умолчанию

Все равно получается ровно столько строк, сколько потоков. Я не знаю что делать уже...
Вот исходный код. Может быть я что-то не правильно делаю...
http://rghost.ru/48526833

Последний раз редактировалось babay89, 02.09.2013 в 12:31.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 10:06.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025