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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Thread. Непонятно работает Suspend и Resume ... вотладке при создании нескольких потоков 
V
    Опции темы
Matematik
Дата 20.8.2007, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

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



Turbo Delphi
Borland® Delphi® for Microsoft® Windows™ Version 10.0.2558.35231 Update 2

По кнопке 1 запускается 5 потоков, которые сразу засыпают suspend. Последний 5йы поток запоминается в переменную t
По кнопке 2 поток t.resume. В результате в memo1 должно записаться символ 5.
Так происходит без отладки.
Если поставить breakpoint на sleep(2000) и повторить действие выше, то запустятся все потоки и в мемо запишется
Код

5
1
3
2
4

Объясните, отладка глючит или я что-то не знаю?[/B]

Код

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TMyThead = class(TThread)
  private
    { Private declarations }
  public
    Tag: String;
  protected
    procedure DoShow;
    procedure Execute; override;
  end;

var
  Form1: TForm1;
  t : TMyThead;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var j : Integer;
begin
  for j:=1 to 5 do
  begin
    t := TMyThead.Create(True);
    t.tag := IntToStr(j);
    t.Resume;
  end;
end;

{ TMyThead }

procedure TMyThead.DoShow;
begin
  Form1.Memo1.Lines.Add(Tag);
end;

procedure TMyThead.Execute;
begin
  while True do
  begin
    Suspend;
    Synchronize(DoShow);
    Sleep(2000); // тут breakpoint
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  t.Resume;
end;

end.


Это сообщение отредактировал(а) Matematik - 20.8.2007, 20:48

Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  test_thread.rar 1,16 Kb
PM MAIL WWW ICQ   Вверх
Mikh@il
Дата 20.8.2007, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Я так понял, тебе надо сделать чтобы потоки писали в memo 1,2,3,4,5
Если так, то используй обьекты синхронизации:

Ищи инфу про Mutex, Semafor, critical section
PM MAIL   Вверх
Matematik
Дата 20.8.2007, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

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



Мне ничего не надо.
Код в отладке работает не так как без нее.
Проблема в том что делая Resum 1го потока, все остальные тоже запускаються
PM MAIL WWW ICQ   Вверх
Snowy
Дата 20.8.2007, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

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



Цитата
  for j:=1 to 5 do
  begin
    t := TMyThead.Create(True);
    t.tag := IntToStr(j);
    t.Resume;
  end;
Что-то я не вижу, где написано, что треды должны спать?
Все созданные треды сразу ресумятся.
PM MAIL   Вверх
Matematik
Дата 20.8.2007, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

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



Snowy, В TMyThead.Execute засыпают
PM MAIL WWW ICQ   Вверх
Mikh@il
Дата 20.8.2007, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



У тя когда стоит breakpoin у тя Sleep не срабатывает, отсюда они все и запускаются
PM MAIL   Вверх
Matematik
Дата 20.8.2007, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

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



Цитата(Mikh@il @  20.8.2007,  21:51 Найти цитируемый пост)
У тя когда стоит breakpoin у тя Sleep не срабатывает, отсюда они все и запускаются 

Не понимаю твою логику
PM MAIL WWW ICQ   Вверх
MetalFan
Дата 20.8.2007, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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


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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

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



MetalFan, пытался усыплять в синхронизации. Тоже самое
PM MAIL WWW ICQ   Вверх
MetalFan
Дата 20.8.2007, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



MSDN не рекомендует использовать усыпление потока для синхронизации...
Цитата(MSDN)
The SuspendThread function is not particularly useful for synchronization because it does not control the point in the code at which the thread's execution is suspended. However, you might want to suspend a thread in a situation where you are waiting for user input that could cancel the work the thread is performing. If the user input cancels the work, have the thread exit; otherwise, call ResumeThread.



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


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

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



Не. Не тот кусочек. Вот этот интереснее.:
Цитата
If the function succeeds, execution of the specified thread is suspended and the thread's suspend count is incremented. Suspending a thread causes the thread to stop executing user-mode (application) code.
This function is primarily designed for use by debuggers. 

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


sceloglauxalbifacies
****


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

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



судя по всему, это глюк отладчика. вот только интересно - он "отпускает" потоки при срабатывании бряка или после продолжения выполнения(это более вероятный вариант)? - добавь вывод времени в мемо. возможно, он(отладчик) при "отпускании" смотрит на предмет нахождения eip(непосредственно или в call-stack'е) контекста замороженных потоков в пределах функции, где стоит бряк.
это так... догадки. нету у меня Turbo Delphi... smile
PM MAIL   Вверх
sentry
Дата 21.8.2007, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Code Monkey
*


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

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



У меня есть Turbo Delphi, решил попробовать. Только я ставил breakpoint'ы в Button1Click. И вот результаты:
1) оказалось, что в зависимости от того, на какой строке стоит бряк, при нажатии на Button1 выводит: либо ничего, либо 1 2 3, либо 1 2 3 4;
2) ставлю бряк там, где 1 2 3 4, запускаю, нажимаю кнопку, попадаю на ту строку, жму F9, снова попадаю туда, снимаю бряк, жму F9 - вывело 1 (а не 1 2 3 4);
3) делаю аналогично там, где 1 2 3, только ничего не выводит.

Может, мне тоже кто-нибудь объяснит, что это такое?  smile 
PM MAIL   Вверх
Matematik
Дата 21.8.2007, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

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



MetalFan, 
Snowy, 
Спасибо что направили в нужное направление. RTFM помогает.

Я так понял что сам отладчик delphi использует SuspendThread и ResumeThread при отладке кода.
Попробую подругому организовать паузу потока.


PM MAIL WWW ICQ   Вверх
Felan
Дата 22.8.2007, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А чего ее делать? Делаешь Event и ручками пускаешь... типа такого (выдрано из проекта как есть)

Метод потока:
Код

procedure TiaParamsToRegMonitor.Execute;
begin
  SetName;

  while (not Terminated) do
  Begin
    try
      fStopEvent.WaitFor(INFINITE);

      If Terminated then Continue;

      if (GetTickCount() - fTimeCount) > ( fRefreshInterval ) then
        begin
          try
            Monitoring; //Функциональный метод потока
          finally
            fTimeCount := GetTickCount;
          end;
        end;

      //пауза что бы поток не кушал такты процессора слишком сильно
      Sleep(100);
    except
      on E: Exception do
        begin
          WriteToLog('Error in thread procedure <' + e.Message + '>');
        end;
    end;
  end;
end;



Создание класса:
Код

constructor TiaParamsToRegMonitor.Create(CreateSuspended: Boolean);
begin
  inherited;

  fCS_AccessToProps := TCriticalSection.Create;
  fStopEvent := TSimpleEvent.Create;
  fStopEvent.ResetEvent;
  setRefreshtInterval(DEF_REFRESH_INTERVAL);
  fRW := TiaRegistryWorker.Create(DEF_SKS_REGISTRY_ROOT, DEF_SKS_REGISTRY_SUBKEY, DEF_SKS_PROGRAM_SUBKEY);

  Priority := tpLowest;
  FreeOnTerminate := False;
end;



Методы пуска и остановки:
Код

procedure TiaParamsToRegMonitor.Start;
begin
  // Здесь может быть какая-нибудь инициализация
  Reset;
end;

procedure TiaParamsToRegMonitor.Stop;
begin
  fStopEvent.ResetEvent;

  setIsStarted( False );
end;



И надое еще не забыть метод аварийного выхода, если у тебя в методе старта потока будет какая-то инициализация. Т.к. для того. что бы корректно выйти из потока надо сначала установить Terminated, а потом отпустить его. Вот что бы без проблем отпустить, без инициализации в методе старт можно сделать так:
Код

procedure TiaParamsToRegMonitor.Reset;
begin
  fTimeCount :=  GetTickCount;
  fStopEvent.SetEvent;
  setIsStarted( True );
end;




--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

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

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

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

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

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


 




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


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

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