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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> упорядоченная синхронизация TThread, доступ к общей переменной упорядочнно 
:(
    Опции темы
pethead
Дата 2.10.2008, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



задача: есть 10000 объектов-классов котрые каждый в своем треде может иметь доступ к общей переменной. доступ каждого синхронизирован любым доступным методом (крит. секция, мютекс, семафор)т.е коллизий нет. но... надо чтобы все потоки работали с переменной каждый 1 раз пока все 10000 объектов не изменят эту переменную. я так понял что не предпринять мер то объекты будут допускаться к переменной по усмотрению планировщика вин32 т.е несколько случайно и не по разу а некоторые объекты могут и не дотронуться до переменной. так? 

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

мда... если не выйдет то придется тупо организовывать в один поток все и в нем по циклу перебирая допускать всех объектов к переменной, но уже не самостоятельным потоком (или потоком все таки? но теперь хоть будет упорядоченно), а просто обычным методом.

Это сообщение отредактировал(а) pethead - 2.10.2008, 17:31
PM MAIL WWW ICQ   Вверх
CodeMonkey
Дата 2.10.2008, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(pethead @  2.10.2008,  17:19 Найти цитируемый пост)
задача: есть 10000 объектов-классов котрые каждый в своем треде может иметь доступ к общей переменной

Ээээ.... этак у вас получается 10к потоков?  smile 
Вы явно что-то не то делаете. Обычно не имеет смысла делать потоков больше, чем число процессоров (с учётом ядер) или для разделения GUI/работы, ввода-вывода, клиентских подключений в службах и т.п.

Цитата(pethead @  2.10.2008,  17:19 Найти цитируемый пост)
 а некоторые объекты могут и не дотронуться до переменной

Такого быть не может.

Добавлено через 5 минут и 16 секунд
Ссылка по теме:
Does Windows have a limit of 2000 threads per process?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Riply
Дата 2.10.2008, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

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



Цитата(CodeMonkey @  2.10.2008,  17:38 Найти цитируемый пост)
Такого быть не может.


Если поток "вызвал ждущую" функцию с конечным интервалом, то, imho, возможно.

"Тут возникает интересный вопрос. Если несколько потоков ждет один объект ядра, какой из них пробудится при освобождении этого объекта? Официально Microsoft отвечает на этот вопрос так: «Алгоритм действует честно" Что это за алгоритм, Micro soft не говорит, потому что нс хочст связывать себя обязательствами всегда придер живаться именно этого алгоритма. Она утверждает лишь одно- если объект ожидает ся несколькими потоками, то всякий раз, когда этот объект переходит в свободное состояние, каждый из них получает шанс на пробуждение. 

Таким образом, приоритет потока не имеет значения- поток с самым высоким приоритетом не обязательно первым захватит объект. Не получает преимущества и поток, который ждал дольше всех. Есть даже вероятность, что какой-то поток сумеет повторно захватить объект. Конечно, это было бы нечестно по отношению к другим потокам, и алгоритм пытается не допустить этого. Но никаких гарантий нет." (с) Jeffrey Richter 


Т.е. если мы ожидаем не INFINITE-ое время, то можем и не добраться smile 



PM MAIL   Вверх
CodeMonkey
Дата 2.10.2008, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Riply @  2.10.2008,  18:12 Найти цитируемый пост)
Если поток "вызвал ждущую" функцию с конечным интервалом, то, imho, возможно.

Ну это очевидно smile


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Riply
Дата 3.10.2008, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

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



Цитата(CodeMonkey @  2.10.2008,  18:33 Найти цитируемый пост)
Ну это очевидно 


Ну, это кому как. smile
Просто, раз уж речь зашла об "упорядоченной синхронизации",
то я сочла уместным показать к каким выводам можно прийти, оприраясь на Рихтера.
А именно: Допустим у нас есть два потока. 
Пусть каждый из них ожидает объекта синхронизации, захватывает ресурс, 
удерживает его в течении 1 милисекудны, отдает и снова входит в режим ожидания.
И пусть у первго потока приоритет TimeCritical, а у второго Idle.
Мы их запускаем и ждем, допустим, на час ( или два smile  ).
Если утверждение Рихтера истинно, то существует отличная от нуля вероятность,
что первый поток (который TimeCritical) так ни разу и не захватит объект.

Например, для меня, этот факт не является "ну уж соль очевидным" smile
А выводы из этого можно сделать довольно плачевные.
Варианты типа зашли в ресурс и увидев, что мы здесь раньше чем надо, быстренко вышли - не прокатывает smile

PM MAIL   Вверх
CodeMonkey
Дата 3.10.2008, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Riply @  3.10.2008,  00:45 Найти цитируемый пост)
Если утверждение Рихтера истинно, то существует отличная от нуля вероятность,

Не торопись smile
Конкретно в твоём примере это не так (вообще в любом разумном сценарии с двумя потоками это невозможно).
Два потока. Поток с низким приоритетом захватил ресурс. Поток с высоким приоритетом пытается захватить ресурс и ждёт поток с низким. Поток с низким приоритетом после вашей обещанной 1 милисекудны отпускает ресурс. Кто его тут же получает? Поток с высоким приоритетом!
Чтобы поток с высоким приоритетом не получил ресурс, необходимо чтобы вместе с ним этот ресурс ждал бы ещё третий поток.

Цитата(Riply @  3.10.2008,  00:45 Найти цитируемый пост)
Мы их запускаем и ждем, допустим, на час ( или два   ).Если утверждение Рихтера истинно, то существует отличная от нуля вероятность,что первый поток (который TimeCritical) так ни разу и не захватит объект.

Да. Но эта вероятность исчезающе мала. Теоретически - да, это возможно, но на практике - маловероятно.
С вероятностями нужно аккуратно. Вон, есть же вероятность, что ваш свеже сгенеренный GUID совпадёт ещё с чьим-то. Но, ничего, обходимся же как-то smile

Цитата(Riply @  3.10.2008,  00:45 Найти цитируемый пост)
А выводы из этого можно сделать довольно плачевные.

Утверждение Рихтера как раз таки гарантирует невозможность (практическую!) сценария, при котором поток не получит ресурс. Не надо только сводить всё к крайностям - очевидно, что если у вас 11 потоков, каждый из которых работает над ресурсом 1 секунду, а ресурс ждёт не более 10 секунд, то гарантировано будет как минимум 1 поток, который не успел поработать над ресурсом (именно поэтому, я сказал, что для ограниченного времени ожидания этот факт очевиден). 
Алгоритм системы как раз все свои силы направляет на предотвращение ситуации, когда поток не получит ресурса. Гарантий нет, да. Но и с GUID нет гарантий уникальности. Но вся его сущность направлена на обеспечение этой уникальности.

Это сообщение отредактировал(а) CodeMonkey - 3.10.2008, 08:42


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
CodeMonkey
Дата 3.10.2008, 08:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Смотри, даже если взять твой сценарий с двумя потоками.
Нет гарантий, что поток будет держать ресурс 1 милисекуду! Вот их уже действительно нет. Поток может быть вытеснен вообще другим процессом с высоким приоритетом. Машина вообще может в спячку уйти. Много, много чего может случиться.
Что же мы получим?
Поток с низким приоритетом захватил ресурс, поток с высоким начинает его ждать (положим минуту, ну пять минут максимум). В это время в обработке ресурса у первого потока происходит задержка (машина ушла в спячку). Значит, поток с высоким приоритетом за всё своё время не успеет ни разу потрогать ресурс.
Ваш простейший сценарий. Два потока. А диспетчер, который отвечает за пробуждение потоков, даже не получил шанса проявить себя, т.к. второй поток вылетел по таймауту раньше, чем первый отпустил ресурс!
Вот ещё одно доказательство очевидности вышеуказанного факта для случая с конечным ожиданием ресурса smile

P.S. Конечно, этот сценарий опять-таки маловероятен, но он просто иллюстрирует:
Цитата(Riply @  2.10.2008,  18:12 Найти цитируемый пост)
Если поток "вызвал ждущую" функцию с конечным интервалом, то, imho, возможно.
 smile 



--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Riply
Дата 3.10.2008, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

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



Цитата(CodeMonkey @  3.10.2008,  08:23 Найти цитируемый пост)
необходимо чтобы вместе с ним этот ресурс ждал бы ещё третий поток.


Угу, согласна, в сценарий надо добавить третий поток - заглушку.

Цитата(CodeMonkey @  3.10.2008,  08:23 Найти цитируемый пост)
Да. Но эта вероятность исчезающе мала


Не "исчезающе мала", а "отлична от нуля" - это совсем разные вещи smile

Цитата(CodeMonkey @  3.10.2008,  08:23 Найти цитируемый пост)
Теоретически - да, это возможно, но на практике - маловероятно


Так и пример у нас надуманный, а на практике мы имеем:
 "10000 объектов-классов котрые каждый в своем треде может иметь доступ к общей переменной"  smile
А если серьезно, то я хотела сказать что при необходимости "упорядоченной синхронизации"
разумного числа потоков варианты типа "заскочил - проверил - вышел" не годятся.

Цитата(CodeMonkey @  3.10.2008,  08:40 Найти цитируемый пост)
Нет гарантий, что поток будет держать ресурс 1 милисекуду


Хороший пример, понравился.

P.S.
 Ну вот видишь, как дела обстоят, а ты "очевидно, да очевидно"  smile

На тему этого "очевидно", приведу цитату из "Физики продолжают шутить":

"В подобных случаях читатель, пытаясь самостоятельно сделать тот шаг, который автору представлялся очевидным, чаще всего оказывается в положении студентов на одной лекции по математике, о которой я недавно читала. Профессор, стоя у доски, был погружен в длиннейший вывод. В каком-то месте он произнес стандартную фразу «отсюда с очевидностью вытекает Следующее» и написал длинное и сложное выражение, абсолютно не похожее ни на что из написанного ранее. Затем он заколебался, на его лице появилось озадаченное выражение, он что-то пробормотал и прошел из аудитории в свой кабинет. Появившись оттуда через полчаса, он с довольным видом объяснил аудитории: «Я был прав. Это, действительно, совершенно очевидно».
"


smile
PM MAIL   Вверх
CodeMonkey
Дата 3.10.2008, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Riply @  3.10.2008,  09:55 Найти цитируемый пост)
А если серьезно, то я хотела сказать что при необходимости "упорядоченной синхронизации"разумного числа потоков варианты типа "заскочил - проверил - вышел" не годятся.

Да, это я понял ;)
И согласен, что не годятся. Но не по этой причине smile

Потому что в данном случае будет использоваться бесконечное ожидание. Смысл делать его конечным? Чтобы пользователь не ждал, если работа займёт значительное время? Не уверен, что это имеет значение в этом сценарии, но даже так - мы просто выйдем по таймауту и будет всё чинно и штатно.
А не годится это по той причине, что потоки будут постоянно дёргать счётчик. Это называется pooling, который плох по определению smile))))
Более того, как я уже сказал, плох и сам подход. Потоков больше 10 - это уже повод задуматься, а больше 200 - явный пример неправильно спроектированной программы.

Цитата(Riply @  3.10.2008,  09:55 Найти цитируемый пост)
Не "исчезающе мала", а "отлична от нуля" - это совсем разные вещи 

Ок, это зависит от способа интерпретации слов Рихтера smile))  А не в курсе, где у самой MS об этом написанно? Пролистал MSDN - не заметил ничего такого.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Riply
Дата 3.10.2008, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

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



Цитата(CodeMonkey @  3.10.2008,  10:42 Найти цитируемый пост)
 А не в курсе, где у самой MS об этом написанно? Пролистал MSDN - не заметил ничего такого. 


Увы :(
Когда первый раз прочитала об этом у Рихтера, тоже сразу побежала в MSDN - и неудачно.
PM MAIL   Вверх
Romikgy
Дата 7.10.2008, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

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



А не лучше ли (при поставленой задаче автора) создать Н-ное число эвантов, и поочереди их активировать , и в потоке после синхронизации отключать активацию что будет поводом (для манагера потоков ) об активации следующего потока


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Riply
Дата 23.10.2008, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

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



Цитата(CodeMonkey @  3.10.2008,  08:23 Найти цитируемый пост)
Не торопись 
Конкретно в твоём примере это не так (вообще в любом разумном сценарии с двумя потоками это невозможно).


Если кому интересно...    smile 
CS Vista

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


Эксперт
***


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

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



Во, отличная ссылка! Демонстрирует, что мы не должны опираться на алгоритм планировщика. Довольно удивительное поведение. Удивительно оно в первую очередь тем, что встречается на двухядерной системе. 
Ключевым компонентом здесь является немедленный захват ресурса после его освобождения: т.е. LeaveCriticalSection(CS); EnterCriticalSection(CS);
Действительно, на однопроцессорной машине после LeaveCriticalSection первый поток вполне может не исчерпать свой квант времени и продолжит выполнение, вызывая EnterCriticalSection (*). Поэтому на однопроцессорной машине такое поведение не было бы удивительным. 
Удивительно, что оно проявляется именно на двухядерной машине. По идее, когда первый поток выходит из LeaveCriticalSection, событие будет в сигнальном состоянии. Это значит, что второй поток немедленно пробуждается (у нас же свободно второе ядро) прямо во время вызова LeaveCriticalSection. Как, интересно, система определяет, что его нужно придержать?

P.S. (*) На самом деле, даже на однопроцессорной машине это не так. См. например: http://forum.sources.ru/index.php?showtopi...t&p=2095611

Цитата(Riply @  3.10.2008,  00:45 Найти цитируемый пост)
удерживает его в течении 1 милисекудны, отдает и снова входит в режим ожидания.

Да, как-то на эти слова я не обратил внимания. Я подразумевал что между освобождением и захватом ресурса поток ещё что-то делает.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Virtuals
Дата 26.10.2008, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



хм а почему бы не использовать, флаговую переменную, где все потоки и будут отмечатся, как только отработают с данными.
используя функции InterlockedXXX (Защищенный доступ к переменным (Interlocked Variable Access) )
там вроде для чтения блокировка не требуется  smile 
а если еще добавить поток, менеджер, который будет выставлять флаг "кому можно получать доступ" /только он туда имеет право писать, остальные только читают/ то вообще влегкую реализовать любой мыслимый порядок доступа smile 

Это сообщение отредактировал(а) Virtuals - 26.10.2008, 19:28
PM MAIL 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.0605 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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