Russian Qt Forum
Ноябрь 24, 2024, 20:42 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Возникновение тупиковых ситуаций (многопоточность)  (Прочитано 5861 раз)
8Observer8
Гость
« : Февраль 01, 2014, 08:11 »

Привет! Вот цитата из книги Макса Шлее:

Цитировать
Работая с многопоточностью, нужно помнить о возможном возникновении тупиковых си-
туаций, когда потоки могут заблокировать друг друга. Представьте себе такую ситуацию,
когда поток заблокировал ресурс "A", а после работы над ним собирается работать с ресур-
сом "B". Другой же поток заблокировал ресурс "B" и по окончании намеревается работать с
ресурсом "A". И вот один из потоков, закончив работу, обнаружил, что нужный ему ресурс
заблокирован другим потоком. Он переходит в режим ожидания, надеясь дождаться раз-
блокировки ресурса, но то же самое делает и другой поток. В итоге — оба ждут друг друга.
Если ни один из этих потоков не освободит занятый им ресурс, то оба "зависнут" и не смо-
гут продолжать свою работу дальше.

Вопрос: как мне кажется, когда поток закончит работу с ресурсом A, то он освободит этот ресурс. Или он будет его держать заблокированным до тех пор, пока не освободится ресурс B?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Февраль 01, 2014, 08:17 »

Как нипишите, так и будет. 
Записан
8Observer8
Гость
« Ответ #2 : Февраль 01, 2014, 08:19 »

Приведите, пожалуйста, простой пример? Я с потоками только начал знакомится. Для меня всё это неочивидно.
Записан
8Observer8
Гость
« Ответ #3 : Февраль 01, 2014, 08:38 »

Я так понимаю, что для правильного использования многопоточности в Qt, нужно сначала изучить примеры из папки "examples/threads", а потом "examples/qtconcurrent". А в дальнейшем использовать только модуль concurrent.

Если кто встречал ресурсы, где бы подробно и просто описывалось "Возникновение тупиковых ситуаций", то поделитесь, пожалуйста.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Февраль 01, 2014, 08:47 »

Приведите, пожалуйста, простой пример? Я с потоками только начал знакомится. Для меня всё это неочивидно.
Код
C++ (Qt)
mutex mut_a;
int a = 0;
 
mutex mut_b;
int b = 0;
 
void thread1()
{
   mut_a.lock();
   if( a == 100500 )
   {
       mut_b.lock();
       b = -100500;
       mut_b.unlock();
   }
   mut_a.unlock();
}
 
void thread2()
{
   mut_b.lock();
   if( b == 1 )
   {
       mut_a.lock();
       a = 0;
       mut_a.unlock();
   }
   mut_b.unlock();
}
 

Если потоки захватили по первому мютексу и условия оказались верны, то эти две нитки навсегда останутся ждать друг друга.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Февраль 01, 2014, 09:15 »

Я так понимаю, что для правильного использования многопоточности в Qt, нужно сначала изучить примеры из папки "examples/threads", а потом "examples/qtconcurrent". А в дальнейшем использовать только модуль concurrent.
Потоки это самый низкий уровень, QtConcurrent это более высокий уровень, позволяющий сконцентрироваться на решение задачи, не думая о потоках и синхронизациях.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Февраль 01, 2014, 09:53 »

Я так понимаю, что для правильного использования многопоточности в Qt, нужно сначала изучить примеры из папки "examples/threads", а потом "examples/qtconcurrent". А в дальнейшем использовать только модуль concurrent.
"многопоточность в Qt" ничем не отличается от "не в Qt". Можно скользить по пути что Вы нарисовали: "прочитать букварь, посмотреть примеры и делать по образцу". В этом нет ничего плохого, устраивает - ну и хорошо. А можно и "копнуть". Если есть желание, вот Вам пара совсем простых задачек

1) Одна нитка принимает символ (напр с клавиатуры), другая его печатает
2) Сделать рекурсивный мутекс самому (на базе QMutex, но без использования QMutex::Recursive)

В процессе решения быстро и хорошо усвоите откуда возникает deadlock (о котором спрашиваете) и многое другое. 
Записан
8Observer8
Гость
« Ответ #7 : Февраль 01, 2014, 09:57 »

Спасибо,парни! Много подкинули пищи для размышления. Теперь это надо переварить. Результат переваривания выложу здесь.
Записан
8Observer8
Гость
« Ответ #8 : Февраль 02, 2014, 07:30 »

Я не очень-то понимал зачем вообще нужны многопоточные программы. Разве что было очевидно, если у компа несколько процессоров, то потоки будут выполнятся одновременно. А вот понять зачем это нужно на компьютере, где один процессор - немог. А тут открыл книжку "Чистый код" Мартин Р. и там есть главы "Многопоточность" (обзорно) и "Приложение A. Многопоточность 2" (подробно) и увидел показательные примеры:

Для примера возьмем однопоточныи агрегатор, который получает информацию
с многих сайтов и объединяет ее в ежедневную сводку. Так как система работает
в однопоточном режиме, она последовательно обращается к каждому сайту, всегда
завершая получение информации до перехода к следующему сайту. Ежедневный
сбор информации должен занимать менее 24 часов. Но по мере добавления новых
сайтов время непрерывно растет, пока в какой-то момент на сбор всех данных
не потребуется более 24 часов. Однопоточной реализации приходится подолгу
ожидать завершения операций ввода/вывода в сокетах. Для повышения 
производительности такого приложения можно было бы воспользоваться 
многопоточным алгоритмом, параллельно работающим с несколькими сайтами.


Или другой пример: допустим, система в любой момент времени работает только
с одним пользователем, обслуживание которого у нее занимает всего одну 
секунду. При малом количестве пользователей система оперативно реагирует на все
запросы, но с увеличением количества пользователей растет и время отклика. 
Никто не захочет стоять в очереди после 150 других пользователей! Время отклика
такой системы можно было бы улучшить за счет параллельного обслуживания
многих пользователей.

Или возьмем систему, которая анализирует большие объемы данных, но выдает
окончательный результат только после их полной обработки. Наборы данных
могут обрабатываться параллельно на разных компьютерах.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Февраль 02, 2014, 07:44 »

Хоть неудобно спорить с таким авторитетом как "Мартин Р.", но все же выскажу свое мнение: все примеры - полное фуфло. Вяло, неконкретно, и вообще дезориентирует доверчивого читателя. Напр подталкивает его к мыслям типа "один коннект - одна нитка", и будет счастье. Впрочем наш читатель не очень-то хочет вникать, смотреть такие обзорняки приятно и ни к чему не обязывает  Улыбающийся
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #10 : Февраль 02, 2014, 14:32 »

Эммм.. Например для ввода/вывода не обязательно ждать выполнения каких-то там сферических операций (на тех же сокетах). Потому что есть такая вешь - асинхронный ввод/вывод, где можно обойтись вообще одним потоком для всех сокетов, и прочих ресурсов ввода/вывода. А вот уже обработку/подготовку принятых/передаваемых данных можно/нужно переносить в отдельные потоки. Например какой нить парсинг или калькуляция может занимать время, поэтому пусть оно не мешает делать I/O, отрисовку GUI или прочие вещи. Хотя, ту же обработку данных можно "размазать" по времени и обойтись одним потоком. Например, делать не сразу все вычисления - а по одной операции.  Улыбающийся  
Записан

ArchLinux x86_64 / Win10 64 bit
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.12 секунд. Запросов: 23.