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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 04.08.2012, 15:28   #1
hon
Форумчанин
 
Регистрация: 08.06.2011
Сообщений: 693
Радость Самоприостановка потока на n милисекунд

Понадобилось мне время от времени очень часто (несколько раз в секунду приостанавливать поток на немножко милисекунд). И тут проблема, при таком коде:

Код:
procedure TTarakanThread.Execute;
label
   mytimer;
begin
   Clipboard.Open;
   Clipboard.SetComponent(frmMain.Tarakan0);
   NewTarakan:=Clipboard.GetComponent(frmMain, frmMain) as TImage;
   Clipboard.Clear;
   Clipboard.Close;

   with NewTarakan do
      begin
      // Name:='Tarakan'+IntToStr(frmMain.Tag); //присвоение нового имени объекту
      Left:=0; Top:=Random(407);
      OnClick:=TarakanDeath;
      Show;
      end;
   frmMain.Tag:=frmMain.Tag+1;

mytimer:
   while (not terminated)and(frmMain.Gamburger.Tag>0) do
      begin
      if NewTarakan.Left+NewTarakan.Width<frmMain.Gamburger.Left then //слева
         begin NewTarakan.Left:=NewTarakan.Left+2;
         NewTarakan.Picture.LoadFromFile('таракан2.png');
         goto mytimer; end;
      if NewTarakan.Left>frmMain.Gamburger.Left+frmMain.Gamburger.Width then //справа
         begin NewTarakan.Left:=NewTarakan.Left-2;
         NewTarakan.Picture.LoadFromFile('таракан4.png');
         goto mytimer; end;
      if NewTarakan.Top+NewTarakan.Height<frmMain.Gamburger.Top then //сверху
         begin NewTarakan.Top:=NewTarakan.Top+2;
         NewTarakan.Picture.LoadFromFile('таракан3.png');
         goto mytimer; end;
      if NewTarakan.Top>frmMain.Gamburger.Top+frmMain.Gamburger.Height then //снизу
         begin NewTarakan.Top:=NewTarakan.Top-2;
         NewTarakan.Picture.LoadFromFile('таракан1.png');
         goto mytimer; end;
      frmMain.Eat; Sleep(10);
   end;
end;
вызов Sleep приостанавливает не только вызвавший его поток, а и всю программу.
Как сделать, чтобы приостанавливался только поток?
hon вне форума Ответить с цитированием
Старый 04.08.2012, 15:44   #2
InternetStranger
php / delphi
Форумчанин
 
Аватар для InternetStranger
 
Регистрация: 10.06.2007
Сообщений: 175
По умолчанию

Точно не скажу, но вроде никак (в том виде как вы хотите). Если только в winAPI чего-нить полезное есть. Сам поток усыпить себя, в принципе, сможет, только вот самому проснуться у него не получится (ибо крепко спит)). Надо, чтобы его кто-то другой разбудил.
Как вариант можно занять его чем-нибудь.
Код:
for i:=1 to 10000 do ;
А вообще проблемы синхронизации (если об этом речь) лучше решать семаформами/мьютексами и прочими прелестями винды.
G.Azamat { Web Development / Computer simulation }
Начинающий программист думает, что в килобайте 1000 байтов, а законченный уверен, что в километре 1024 метра.
InternetStranger вне форума Ответить с цитированием
Старый 04.08.2012, 16:07   #3
volvo877
Форумчанин
 
Аватар для volvo877
 
Регистрация: 01.06.2009
Сообщений: 108
По умолчанию

Цитата:
вызов Sleep приостанавливает не только вызвавший его поток, а и всю программу.
Неправда. Как и написано в MSDN:
Цитата:
Suspends the execution of the current thread until the time-out interval elapses.
, приостанавливается только поток. Хочешь проверить? Сделай Execute потока состоящей из одного Sleep(30000), и запусти его. Если Sleep "замораживает" всё приложение - то ничего больше с формой ты сделать не сможешь, пока поток не завершится. Однако, форма прекрасно реагирует на события - "спит" только поток. Значит, что-то еще накрутил у себя в приложении...
volvo877 вне форума Ответить с цитированием
Старый 04.08.2012, 16:31   #4
Кольша
Далеко не
Участник клуба
 
Аватар для Кольша
 
Регистрация: 11.08.2011
Сообщений: 1,512
По умолчанию

Код:
if needstop then
sleep(3000);///спим 3 сикунды
Кольша вне форума Ответить с цитированием
Старый 04.08.2012, 16:39   #5
hon
Форумчанин
 
Регистрация: 08.06.2011
Сообщений: 693
По умолчанию

Цитата:
Сообщение от volvo877 Посмотреть сообщение
Неправда. Как и написано в MSDN:
, приостанавливается только поток. Хочешь проверить? Сделай Execute потока состоящей из одного Sleep(30000), и запусти его. Если Sleep "замораживает" всё приложение - то ничего больше с формой ты сделать не сможешь, пока поток не завершится. Однако, форма прекрасно реагирует на события - "спит" только поток. Значит, что-то еще накрутил у себя в приложении...
Я даже форму закрыть не могу, закрывается не сразу.
hon вне форума Ответить с цитированием
Старый 04.08.2012, 17:12   #6
volvo877
Форумчанин
 
Аватар для volvo877
 
Регистрация: 01.06.2009
Сообщений: 108
По умолчанию

Можно присоединить минимальный проект, иллюстрирующий проблему? Проект в аттаче показывает, что замораживается только поток, можешь показать проект, иллюстрирующий обратное?
Вложения
Тип файла: zip m_thread.zip (261.8 Кб, 6 просмотров)
volvo877 вне форума Ответить с цитированием
Старый 04.08.2012, 17:14   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Как вариант можно занять его чем-нибудь.
активное ожидание, самое хучшее в многозадачной среде(искл если не обойтись).

ТС, не в синхронизе часом слипите поток?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 04.08.2012, 17:29   #8
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,689
По умолчанию

frmMain - может многократное обращение к форме из потока приводит к залипанию (кстати, это не кошерно)
goto mytimer можно на continue заменить
eoln вне форума Ответить с цитированием
Старый 04.08.2012, 18:02   #9
InternetStranger
php / delphi
Форумчанин
 
Аватар для InternetStranger
 
Регистрация: 10.06.2007
Сообщений: 175
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
активное ожидание, самое хучшее в многозадачной среде(искл если не обойтись).
Да, зло. А приведенный мной выше пример еще и процессор нагрузит (все, что выделит система этому потоку). Поэтому только в качестве костыля (забыл написать об этом выше).

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
ТС, не в синхронизе часом слипите поток?
Цитата:
Сообщение от eoln Посмотреть сообщение
frmMain - может многократное обращение к форме из потока приводит к залипанию (кстати, это не кошерно)
Так к форме напрямую вообще обращаться не положено, ибо, помнится, форма однопоточна. Только в методе синхронизации, который скорее всего не используется. Поэтому и залипает.

ps: отрекаюсь от предыдущего своего поста. Поленился прочитать про sleep() ))
G.Azamat { Web Development / Computer simulation }
Начинающий программист думает, что в килобайте 1000 байтов, а законченный уверен, что в километре 1024 метра.

Последний раз редактировалось InternetStranger; 04.08.2012 в 18:04.
InternetStranger вне форума Ответить с цитированием
Старый 04.08.2012, 18:30   #10
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,689
По умолчанию

Цитата:
Сообщение от InternetStranger Посмотреть сообщение
Так к форме напрямую вообще обращаться не положено
Я и написал, что так делать плохо .
Цитата:
Сообщение от InternetStranger Посмотреть сообщение
Только в методе синхронизации, который скорее всего не используется. Поэтому и залипает.
Тоже думаю, что синхронизации нет. Я имел в виду, что возможно frmMain.Eat что-то долгое с формой делает (даже если синхронизировать, то залипание может не исчезнуть). Оттуда можно всё по максимуму в поток запихнуть (циклы, вычисления разные и т.п.), а синхронизировать только непосредственное обращение к форме/компонентам.
eoln вне форума Ответить с цитированием
Ответ


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

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Должно быть 3 потока. А диспетчер задач показывает, что потока создано 2 BEL9ILLI Общие вопросы Delphi 3 06.12.2011 20:26
Оптимизация потока Ghost of Night Общие вопросы Delphi 9 14.07.2011 03:18
Как узнать номер потока из самого потока? GaMeSTeR Помощь студентам 0 03.12.2010 09:50
Номер потока KoBRaAndrey Общие вопросы Delphi 1 01.06.2010 02:27
Уничтожение потока SNUPY Общие вопросы Delphi 2 11.02.2009 22:47