• 0
Winexcel

DealLock или что сделать чтобы его получить

Вопрос

Здравствуйте, интересует такой вопрос, хочу получить deadLock в своём приложении, может ли кто объяснить что нужно сделать чтобы его получить при обращении потока к GUI? написал небольшой пример который запускает по нажатию на Button поток и устанавливает в TLabel значение из внутреннего счетчика, но никак не могу получить зависание приложения, если кто знает объясните пожалуйста как это сделать и в каких случаях возможен dealLock в FMX.

deadlock.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

14 ответов на этот вопрос

  • 0

Во-первых ни в коем случае нельзя обращаться к визуальным компонентам напрямую без синхронизации, да и вообще к любым разделяемым ресурсам. Во-вторых deadlock в FMX ничем не отличается от deadlock на VCL или на WinAPI, почитать можно здесь http://forum.vingrad.ru/topic-60076.html

Конкретно в приведённом примере достаточно обернуть изменение метки в Synchronize

    TThread.Synchronize(nil, procedure
      begin
        Form4.Label1.Text:=i.ToString;
      end);

и после запуска потока вызывать MyThread.WaitFor; - получите deadlock.

Winexcel понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
14 часа назад, Maximus сказал:

Во-первых ни в коем случае нельзя обращаться к визуальным компонентам напрямую без синхронизации, да и вообще к любым разделяемым ресурсам. Во-вторых deadlock в FMX ничем не отличается от deadlock на VCL или на WinAPI, почитать можно здесь http://forum.vingrad.ru/topic-60076.html

Конкретно в приведённом примере достаточно обернуть изменение метки в Synchronize


    TThread.Synchronize(nil, procedure
      begin
        Form4.Label1.Text:=i.ToString;
      end);

и после запуска потока вызывать MyThread.WaitFor; - получите deadlock.

Огромное спасибо за материал, ознакомлюсь с ним в ближайшее время, у меня возник такой вопрос, а могу ли я ТОЛЬКО читать из Form4.Label1.Text в самом потоке секции Execute значение бесконечно без синхронизации, например в переменную типа String? То есть могу ли я чисто только счиывать значения из GUI без синхронизации этого.

Изменено пользователем Winexcel

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

нет. не делайте так

вообще даже не должна возникать сама идея что-то читать "с экрана"

для этого существуют структуры данных

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
3 минуты назад, krapotkin сказал:

нет. не делайте так

вообще даже не должна возникать сама идея что-то читать "с экрана"

для этого существуют структуры данных

а к чему может привести такое?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
2 часа назад, Winexcel сказал:

а к чему может привести такое?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

у гансмокера есть старая статья про глобалки и использование интерфейса

там ни добавить ни убавить

для курсовой пойдет любой хоррор-стайл программирования

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

такой код непереносим, немасштабируем, нетестируем, нечитаем, неподдерживаем

kami понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
9 часов назад, Камышев Александр сказал:

cs->Enter(); cs->Enter();

не-а.

В пределах одного потока можно хоть MaxInt раз входить в критическую секцию, ничего от этого не замерзнет.

А вот

CS.Enter;
myThread.Start; // и внутри execute тоже CS.Enter
myThread.WaitFor;

 

Главный поток вошел в критическую секцию, запустил доп.поток и ожидает, пока тот завершится (надуманный пример, не надо делать поток ради делания потока).

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

Итого - главный поток висит, ожидая пока завершится доп., а доп.висит, ожидая пока освободится секция.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
4 часа назад, krapotkin сказал:

у гансмокера есть старая статья про глобалки и использование интерфейса

там ни добавить ни убавить

для курсовой пойдет любой хоррор-стайл программирования

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

такой код непереносим, немасштабируем, нетестируем, нечитаем, неподдерживаем

Не могли бы ткнуть на эту статью? Она отвечает на мой вопрос по чтению как раз да?)

Изменено пользователем Winexcel

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
8 часов назад, krapotkin сказал:

нет. не делайте так

вообще даже не должна возникать сама идея что-то читать "с экрана"

для этого существуют структуры данных

Под структурами данных понимаются какие-либо переменные или записи/record(как пример)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
14 часа назад, Winexcel сказал:

Под структурами данных понимаются какие-либо переменные или записи/record(как пример)?

и классы

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
19 часов назад, kami сказал:

В пределах одного потока можно хоть MaxInt раз входить в критическую секцию, ничего от этого не замерзнет.

мдя согласен, счетчик только увеличивается

тогда еще проще:

TSimpleEvent *event = new TSimpleEvent(NULL);
event->WaitFor( INFINITE );

замри :)

Изменено пользователем Камышев Александр

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
49 минут назад, Камышев Александр сказал:

тогда еще проще:

а это не дедлок. Это, грубо говоря,

while true do sleep(maxint);

т.е просто засыпаем текущий поток, не влияя при этом на остальные.

Дедлок - это когда один поток ждет реакции от другого потока, который ждет реакции от первого потока. Возможно - даже через третьи, четвертые... руки. Получается кольцо ожидания. В приведенном примере никакой зависимости от другого потока, у которого зависимость от этого потока - нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
18 часов назад, kami сказал:

а это не дедлок. Это, грубо говоря,


while true do sleep(maxint);

т.е просто засыпаем текущий поток, не влияя при этом на остальные.

Дедлок - это когда один поток ждет реакции от другого потока, который ждет реакции от первого потока. Возможно - даже через третьи, четвертые... руки. Получается кольцо ожидания. В приведенном примере никакой зависимости от другого потока, у которого зависимость от этого потока - нет.

while(1) Sleep(INT_MAX) 

- это грубо, но можно еще брутальней:

while(1){}

 если так принципиально, для успокоения, можно создать еще поток, передать ему ссылку на event, добавить код 

event->SetEvent()

и не запуская на выполнение уйти в WaitFor, тогда все в порядке: два потока, оба ждут.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

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

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу