| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Потоки и синхронизация вызовов функций из dll |
| Автор: Loony 25.5.2008, 21:19 |
| Добрый вечер, Уважаемые! Скажу сразу, с Delphi не очень дружу, могу сморозить чушь! Вопросы: 1. Правльным ли будет использовать в моем случае критические секции? 2. Если нет, то что надо использовать!? 3. Чем грозит длительная блокировка потока и грозит ли чем-то вообще? 4. Возможно при использовании Delphi с потоками есть еще какие-то ньюансы? P.S. Delphi 7, если это важно! |
| Автор: Loony 25.5.2008, 22:48 |
| То есть, на первый вопрос ответ - да!? |
| Автор: Alexeis 26.5.2008, 13:39 | ||
Я имел ввиду разместить критическую секцию внутри функции. Представь, что функцию вызываешь из разных модулей, тогда критическую секцию прийдеться объявлять в одном из общих модулей, да и забыть вставить ее можно случайно, а если критическую секцию вставить в функцию, то во первых понадобиться всего одна критическая секция во вторых, когда второй поток попытается вызвать функцию, то он зайдет и автоматом заблокируется. Есть еще вариант сделать мьютекс с таймаутом. Т.е. второй поток зайдет в функцию подождет 100мс, увидит что ждать нужно долго и выйдет досрочно с специальным кодом ошибки, после чего сможет делать что-то другое и повторить попытку через некоторое время. |
| Автор: Loony 26.5.2008, 14:07 |
| Alexeis, если имеется ввиду внутри функции длл, то сделать этого не получится, исходников длл нет. |
| Автор: Felan 26.5.2008, 14:20 |
| Неважно. Можно сделать модуль-обертку, где будут просто вызываться нужные функции из длл + синхронизация. От себя добавлю, что синхронизировать нужно только доступ к данным, причем, когда существует доступ на изменения. Синхронизировать доступ на чтение к данным которые не изменяются не имеет смысла. Синхронизировать функции генерации чего-либо, если при генерации не используются глобальные данных, которые существуют И изменяются между вызовами таких функций, тоже синхронизировать смысла нет. |
| Автор: Rennigth 26.5.2008, 15:07 | ||
эт ты зря... |
| Автор: Alexeis 26.5.2008, 15:39 |
Это еще почему? По моему синхронизация не нужна даже при условии что открывается только доступ для чтения. Важно чтобы не было даже косвенного влияния того что читается на то что пишется. Гарантия неизменности это дополнительное необязательное условие. Представим себе ситуацию. На сервер непрерывно поступают данные о прогнозе погоды по разным регионам. Существует много служб, которые достают эти данные и публикуют у себя. Ситуация что в прогноз на хабаровск будет текущий, а на Москву будет за прошлый час устраивает всех. Тем не менее, общий прогноз находиться на стадии записи, тогда как доступ к отдельным записям доступен всегда. Если есть гарантия неизменности то вообще идеально... |
| Автор: Loony 26.5.2008, 16:24 |
| Felan, обертки уже сделал! |
| Автор: Rennigth 26.5.2008, 16:58 |
| Alexeis, а что получится если два потока будут одновременно читать из одного места? * ушел читать rtfm... но мне всегда казалось что... |
| Автор: Alexeis 26.5.2008, 17:15 | ||
Такое происходит и постоянно. Например флаги мьютекса или семафора. К ним же происходит обращение из нескольких потоков, тот же счетчик семафора. Физически память не позволит одновременно обратиться даже при двух процах, потому это в любом случае будет последовательно. |
| Автор: Felan 27.5.2008, 07:29 | ||||
Ниче не будет. Оба прочитают и все. Если используются примитивные типы, то скорее всего ничего не будет даже если третий будет одновременно писать, а вот если классы, стринги, записи и т.п., то может получится так, что один поток начал писать, а второй начал читать, первый притормозил, а второй прочитал мусор...
Ты не путай, это специальные объекты, доступ к которым контролирует система. А к память как раз даже очень позволяет обращаться одновременно из разных потоков. Для этого и существует синхронизация. |
| Автор: Alexeis 27.5.2008, 07:59 | ||||
И чем же системам ограничивает? Там просто атомарные типы отвечают за состояние, потому если один записал true, то другой не сможет прочитать что-то на середине записи состояния true.
Ну тут все зависит организации самого доступа и что считать противоречивым состоянием. Это определяется в каждом конкретном случае отдельно. Излишняя синхронизация тоже вредна, более того она может приводить самоблокировке системы там где можно было без этого обойтись. |
| Автор: Felan 27.5.2008, 08:50 | ||||
Внутренними правилами ограничивает. Не путай системные спец. объекты и доступ к памяти.
Тут все зависит от везения. Т.к. resume останавливает поток в произвольном месте между процессорными инструкциями, и если запись данных занимает болше одной инструкции, то вероятна ситуация, когда записано только половина данных. И вероятность пропорциональна количеству потоков и частоте обращений. Поэтому и рекомендуется явно выделять точки ожидания для потока. Что такое самоблокировка? Если криво сделана синхронизация, так, что она приводит к дедлоку, то это именно криво сделанная синхронизация. Само обычно ничего не бывает |
| Автор: Alexeis 27.5.2008, 11:14 | ||
Например потоки работают с 2мя записями. Для этого она захватывает одну и ждет вторую, в это время второй поток захватил вторую и ждет первую, которую занял первый. Таким образом 2 потока ждут друг друга. Возможны и другие более сложные ситуации с косвенной связью, потому избыточная синхронизация также вредна как и недостаточная. |
| Автор: Felan 27.5.2008, 11:31 | ||
Это называется Deadlock. И это значит, что неправильно сделана синхронизация в принципе. Избыточная синхронизация грозит только уменьшением производительности. И уж тем более это происходит не само, так что про САМОблокировке и речи быть не может ;) |
| Автор: bems 27.5.2008, 17:18 | ||
|