Про интервью в Майкрософт проконсультируйте pls

__Vlad__
Новичок
Posts: 52
Joined: 24 Oct 1999 09:01
Location: Santa Clara, CA

Post by __Vlad__ »

Спать с захваченным mutex это иметь проблему на свою голову.

STL не является thread safe так как он изначально разрабатывался для разных платформ с различными механизмами синхронизации. Попробуйте из двух различных потоков подабавлять элементы в контейнер без дополнительной синхронизации :nono#:
Big Cheese
Уже с Приветом
Posts: 1211
Joined: 02 Jul 2000 09:01
Location: SFBA

Post by Big Cheese »

[quote:d2a36e3fe4="__Vlad__"]Спать с захваченным mutex это иметь проблему на свою голову.

STL не является thread safe так как он изначально разрабатывался для разных платформ с различными механизмами синхронизации. Попробуйте из двух различных потоков подабавлять элементы в контейнер без дополнительной синхронизации :nono#:[/quote:d2a36e3fe4]

Спать с мьютексом? - оррригинально :mrgreen: ((с) поручик Ржевский) (Извините, не удержался) Если я правильно (ибо были случаи :umnik1: )понимаю, речь шла о случае, когда состояние потока (thread) контролируется не самим потоком (для простоты: WaitForXXX -> lock YYY -> doSomething -> unlock YYY -> WaitForXXX), а внешним потоком (диспетчером) который вызывает Suspend/ResumeThread, etc. руководствуясь определенной логикой. В каком случае, в управляемых потоках нет смысла реализовывать WaitFor...., но любой из управляемых потоков может быть suspended в состоянии doSomething, т.е. "уснуть с мьютексом".
Насчет STL: не было утверждения, что STL является thread-safe, смысл был в том, что [quote:d2a36e3fe4="tengiz"]... несмотря на то, что библиотека в целом thread-neutral, есть довольно много ситуаций, когда для защиты глобальных объектов STL использует глубоко закопанную в недрах своей реализации сихронизацию.

И вот тут и вылезают проблемы, так как thread-neutral STL является таковой, вообще говоря, только в строго стандартном случае.[/quote:d2a36e3fe4]
Т.е. _конкретная_ реализация STL использует синхронизацию для своих внутренних нужд.

PS: прошу прощения за вольную интерпретацию постинга Тенгиза
__Vlad__
Новичок
Posts: 52
Joined: 24 Oct 1999 09:01
Location: Santa Clara, CA

Post by __Vlad__ »

У последователей поручика проблемы будут не с головой, а с другим местом :mrgreen: .

В изначально приведенном примере thread засыпал сам при захваченном mutex. И что бы при этом не делала система или другой поток, mutex он не отдаст пока спит (а с кем же он тогда спать будет :D ). Если же диспетчеризацией занимается выделенный поток, то может быть мне кто то сможет объяснить в чем разница для синхронизации и конкретно для STL если бы диспетчеризацией занималась система?

Что такое thread neutral? Appartment neutral знаю, thread safe или unsafe знаю, high thread affinity знаю, thread neutral не знаю :D .
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Post by tengiz »

[quote:ad8bdaccb4="__Vlad__"]Что такое thread neutral? Appartment neutral знаю, thread safe или unsafe знаю, high thread affinity знаю, thread neutral не знаю :D .[/quote:ad8bdaccb4]
Thread-neutral означает, что для обеспечения сихронизации доступа к ресурсам, которые доступны пользователю, библиотека ничего сама не делает. Т.е. в Вашем примере вставки элементов, скажем, в один и тот же map из двух разных потоков, защиту map, разумеется должен обеспечивать программист - Вы всё правильно говорите. Однако в случае, когда разные потоки работают с разными экземплярами map, ничего делать не нужно. Несмотря на наличие глобальных данных, используемыми всеми map одного типа (в случае DinkumWare STL это недоступный пользователю null node) синхронизация обеспечивается самой библиотекой.

Другими словами - Вам обещается, что за то, что Вы сами в принципе не можете защитить, отвечает сама система. Всё остальное – строго под Вашу ответственность. И при условии, что Ваш код, работающий с библиотекой, спроектирован правильно в смысле синхронизации, сама библиотека никаких проблем не внесёт. Если Вы, конечно, пользуетесь стандартной диспетчеризацией.

Теперь по поводу примера - наверное, мне не нужно было настолько всё упрощать и видимо было бы меньше вопросов, если бы я сразу подробнее бы всё пояснил. Тем не менее:

В системах обработки транзакций основанных на блокировках один из способов обеспечения непротиворечивости – это следование протоколу двухфазной блокировки, суть которого грубо в том, что любая транзакция состоит из двух фаз:

фаза 1 - это накопление блокировок: при этом ни одна из захваченных ранее блокировок не отпускается до конца транзакции;
фаза 2 - конец транзакции и высвобождение всех накопленных блокировок.

Что означает, что после захвата ресурса А, при попытке захватить ресурс Б в случае, когда тот уже захвачен другой транзакцией, потоку придётся отдать CPU каким-либо способом - т.е. фигурально выражаясь мы "захватили мьютекс и заснули". Вариант одновременного захвата А и Б не работает в случаях когда транзакция заранее не знает, какие ресурсы по ходу дела могут понадобиться, кроме того, таких ресурсов может быть слишком много, чтобы можно было использовать, скажем, WaitForMultipleObjects.

Вполне обычная архитектура высокопроизводительной многопользовательской системы обработки транзакций – это смесь согласованной (кооперативной) и вытесняющей многозадачности. Если обработка ресурса А занимает существенное время, то типичным вариантом является периодическая добровольная отдача контекста, и снова мы "захватили мьютекс и заснули". Та часть кода, для которой естественнее работать в кооперативном режиме должна гарантированно быть таковой (что обеспечивается безусловным соблюдением специфических для конкретной системы соглашений), иначе могут будут проблемы.

Именно в таких участках кода необходимо соблюдать осторожность при использовании сторонних компонент/библиотек – например, неожиданное для системы переключение контекста, которое может произойти при вызове метода компонента, в котором используется стандартная синхронизация, может принести большие неприятности.

Всё, подробнее писать лень - поздно уже. Да и оффтопик сильно затянулся. Если интересно по этому поводу ещё порассуждать – лучше открыть специальную тему.
Cheers
__Vlad__
Новичок
Posts: 52
Joined: 24 Oct 1999 09:01
Location: Santa Clara, CA

Post by __Vlad__ »

[quote:a5b44ed601="tengiz"]Thread-neutral означает, что для обеспечения сихронизации доступа к ресурсам, которые доступны пользователю, библиотека ничего сама не делает. Т.е. в Вашем примере вставки элементов, скажем, в один и тот же map из двух разных потоков, защиту map, разумеется должен обеспечивать программист - Вы всё правильно говорите. Однако в случае, когда разные потоки работают с разными экземплярами map, ничего делать не нужно. Несмотря на наличие глобальных данных, используемыми всеми map одного типа (в случае DinkumWare STL это недоступный пользователю null node) синхронизация обеспечивается самой библиотекой.
[/quote:a5b44ed601]
Это классический пример thread unsafe, т.к. программист должен обеспечивать синхронизацию сам. Это COM компонент может быть appartment neutral когда ему все равно в каком appartment instantiate, но как минимум это подразумевает наличие двух типов appartment. Для STL объекта thread все равны, поэтому проблема не в affinity, а в синхронизации.

Интересно, что произойдет в такой системе, если нужно провести две транзакции которые модифицируют А и Б в разной последовательности. Я так надеюсь, что не deadlock?

Если обработка ресурса занимает существенное время при 100% загруженном CPU то я не понимаю в чем достигается выигрыш если вместо того чтобы как можно скорее захваченный ресурс освободить thread будет отдавать CPU другим потокам которые все равно не могут выполняться так как ждут освобождения ресурса захваченного спящим потоком?
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Post by tengiz »

[quote:9218faabfa="__Vlad__"]Это классический пример thread unsafe, т.к. программист должен обеспечивать синхронизацию сам. Это COM компонент может быть appartment neutral когда ему все равно в каком appartment instantiate, но как минимум это подразумевает наличие двух типов appartment. Для STL объекта thread все равны, поэтому проблема не в affinity, а в синхронизации.[/quote:9218faabfa]
Thread unsafe - это когда никакая синхронизация (за исключением вырожденного случая строго последовательного выполнения) не гарантирует правильной работы. Пример - single-threaded вариант стандартной C runtime библиотеки, где, скажем, нет никакого способа получить гарантированно правильный errno, если работает больше чем один поток. Любая функция, меняющая глобальное состояние неподконтрольным пользователю способом, принесёт кучу проблем и ничего с этим сделать нельзя.

В общем вот такая классификация (я не собираюсь утверждать, что она является общепринятой) с точки зрения того, что должен делать пользователь компонента/библиотеки:

1. thread-unsafe - никакая синхронизация не гарантирует правильную работу;
2. thread-neutral - при правильной синхронизации всё работает;
3. thread-safe - синхронизация не нужна, всегда работает правильно;

[quote:9218faabfa]Интересно, что произойдет в такой системе, если нужно провести две транзакции которые модифицируют А и Б в разной последовательности. Я так надеюсь, что не deadlock?[/quote:9218faabfa]
Конечно случится deadlock, но только же речь идёт о не прикладном, а о системном компоненте, который отвечает за свою часть работы и не может гарантировать правильность или разумность действий прикладного программиста. Например, в любой СУБД, основанной на locking scheduler, легко делается deadlock запуском "правильной" последовательности запросов. Ну и что из этого следует?

[quote:9218faabfa]Если обработка ресурса занимает существенное время при 100% загруженном CPU то я не понимаю в чем достигается выигрыш, если вместо того чтобы как можно скорее захваченный ресурс освободить thread будет отдавать CPU другим потокам, которые все равно не могут выполняться, так как ждут освобождения ресурса захваченного спящим потоком?[/quote:9218faabfa]

Во-первых, cущественное время обработки не всегда означает "100% загруженный CPU". Во-вторых, если все ждут того самого ресурса, то они и не буду претендовать на CPU. В третьих, для многопользовательских систем очень важно уметь справедливо поделить вычислительную мощность системы между всеми пользователями - responsiveness для системы заказа билетов должна остаться по возможности высокой, даже если кто-то запустил сложную обработку архивных данных. Если один из пользователей решает прожорливую проблему, другие не должны оказаться в полном клинче при отсутствии непреодолимого конфликта по ресурсам. И не забывайте, речь шла о системах с частичной кооперативной многозадачностью - та самая "нестандартная диспетчеризация", о которой собственно и шла речь с самого начала.

Уважаемые коллеги, оффтопик сильно затягивается. Если есть желание дальше поговорить, давайте откроем новую тему.
Cheers
__Vlad__
Новичок
Posts: 52
Joined: 24 Oct 1999 09:01
Location: Santa Clara, CA

Post by __Vlad__ »

[quote:eccb25bda6="tengiz"]Thread unsafe - это когда никакая синхронизация (за исключением вырожденного случая строго последовательного выполнения) не гарантирует правильной работы. Пример - single-threaded вариант стандартной C runtime библиотеки, где, скажем, нет никакого способа получить гарантированно правильный errno, если работает больше чем один поток. Любая функция, меняющая глобальное состояние неподконтрольным пользователю способом, принесёт кучу проблем и ничего с этим сделать нельзя.[/quote:eccb25bda6]

Т.е. насколько я понял "правильная" синхронизация заключается в захвате spinlock перед обращением к С runtime и немедленном его освобождении сразу же после возвращения управления вызывающей процедуре. А вот если подержать spinlock еще чуть-чуть и прочитать errno в локальную переменную, это уже вырожденный случай :D . Кроме того multi-threaded вариант стандартной библиотеки является thread-safe, т.к. не требуется никакий дополнительных действий по синхронизации: например malloc не испортит состояние memory manager даже будучи вызванным из разных потоков без какой либо синхронизации.

[quote:eccb25bda6="tengiz"] В общем вот такая классификация (я не собираюсь утверждать, что она является общепринятой) с точки зрения того, что должен делать пользователь компонента/библиотеки:

1. thread-unsafe - никакая синхронизация не гарантирует правильную работу;
2. thread-neutral - при правильной синхронизации всё работает;
3. thread-safe - синхронизация не нужна, всегда работает правильно;
[/quote:eccb25bda6]

Если не изобретать своей собственной классификации, то в общепринятой есть понятие high thread affinity, т.е. объект/библиотека привязаны к одному потоку и вызов из других потоков не гарантирует правильную работу. Существует масса примеров high thread affinity (STA COM object, окно и т.д.). Кроме того есть понятие thread unsafe - от пользователя требуется некоторый набор телодвижений чтобы все работало. Требования могут быть разные, от просто блокировки одновременных обращений, до требования использовать конкретный поток для любых обращений.

[quote:eccb25bda6="tengiz"]Во-первых, cущественное время обработки не всегда означает "100% загруженный CPU". Во-вторых, если все ждут того самого ресурса, то они и не буду претендовать на CPU. В третьих, для многопользовательских систем очень важно уметь справедливо поделить вычислительную мощность системы между всеми пользователями - responsiveness для системы заказа билетов должна остаться по возможности высокой, даже если кто-то запустил сложную обработку архивных данных. Если один из пользователей решает прожорливую проблему, другие не должны оказаться в полном клинче при отсутствии непреодолимого конфликта по ресурсам. И не забывайте, речь шла о системах с частичной кооперативной многозадачностью - та самая "нестандартная диспетчеризация", о которой собственно и шла речь с самого начала.[/quote:eccb25bda6]

Т.е. предположим, что поток A занимается сложной обработкой и вначале захватил mutex, после чего заснул на некоторое время. Тут от пользователя пришел короткий запрос, который требует захвата того же mutex. Т.к. thread B не может захватить этот mutex он засыпает. Имеем два thread-a которые оба спят, пользователь ждет. Через некоторое время просыпается А делает часть работы и опять засыпает. Thread B все равно ждет. В конечном итоге, вместо того чтобы пользователь получил ответ, что запрошенный ресурс недоступен, он прождет все время пока обрабатывается сложный запрос.

[quote:eccb25bda6="tengiz"]Уважаемые коллеги, оффтопик сильно затягивается. Если есть желание дальше поговорить, давайте откроем новую тему.[/quote:eccb25bda6]
Я согласен.
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Post by tengiz »

[quote:ad9764033b="__Vlad__"][quote:ad9764033b="tengiz"]Уважаемые коллеги, оффтопик сильно затягивается. Если есть желание дальше поговорить, давайте откроем новую тему.[/quote:ad9764033b]
Я согласен.[/quote:ad9764033b]

Продолжение здесь: http://forum.privet.com/viewtopic.php?t=22926
Cheers
Big Cheese
Уже с Приветом
Posts: 1211
Joined: 02 Jul 2000 09:01
Location: SFBA

Post by Big Cheese »

Пришла и мне пора писАть то теме топика. Но нет худа без добра, давно хочу попасть в Microsoft, наконец-то "хороший" случай подвернулся. В связи с этим - вопрос: как лучше послать своё резюме, чтобы оно не затерялось в недрах HR? Стоит ли использовать Resume Builder, который есть на сайте MS или просто послать е-мэйл?

Отдельно насчёт того, стоит ли указывать код(ы) позиций? То есть одна из основных причин желания работать в МС - специализация и работа в области transaction processing / OS internals / languages/compilers; но так как специалистом в данных областях я увы! пока не являюсь - логично начать с работы "на подхвате", а несоответствие указанной позиции может послужить причиной отправки моего резюме в мусор, с другой стороны, специализация в GUI или ЗD графике мне не очень интересна..

Вообщем, как увеличить шансы на разговор об утюгах и кофемолках? А то обидно будет - саблей махать учился, а на войну не позвали :mrgreen:

Заранее благодарен за советы.
ami
Уже с Приветом
Posts: 1102
Joined: 15 Feb 2000 10:01
Location: Novosibirsk->Pasadena, CA

Post by ami »

[quote:a0cdc2b29f="segaa"][color=indigo:a0cdc2b29f][i:a0cdc2b29f]То, что мне более всего не нравится в STL, не считая дурной референсинг при копировании string-ов (memory leaks обеспечены :) ), это то, что классы коллекций при удалении объектов автоматически не обнуляют указатели на них...В новом STL-е те же проблемы?[/i:a0cdc2b29f][/color:a0cdc2b29f][/quote:a0cdc2b29f]Вы о чем? std::container<T*> vCollection; vCollection.clear(); - clear() вообше-то не вызывают деструктор T::~T(), и, соответственно, не имеют никакого права обнулять указатели. Более того, все контейнеры в stl, по-стандарту должны быть exception-safe, exception-neutral и не должны налагать дополнительных требований к contained типам, как-то nothrowing destructor, хотя это, имхо, должно быть правилом хорошего тона при создании любого типа...

Return to “Работа и Карьера в IT”