У меня несколько "нубовский" вопрос по .Net Я думаю, что почти каждый из вас видел Google Chrome browser. И как вы уже знаете, что каждая вкладка у это веб броузера в отдельном процессе. Как я понял, это сделано для того, что бы если одна вкладка повисла — она не потянет полностью все приложение. Так вот вопрос в том, что — почему они сделали именно так? Ведь многопоточностью можно достичь, по сути, такого же результата?
Когда я гуглил по поводу имплементации такого плана приложения (вкладка — процесс) я наткнулся на советы, что лучше делать это через домены приложения. Типа одна вкладка — один домен.
Так вот вопрос, кто-нибудь уже проектировал и делал такие приложения, которые предусматривают отказоустойчевость, если хотя бы один элемент повис? И какие плюсы и минусы а) разных доменов б) разных процессов в) разных потоков?
Как по мне видится, что разные потоки — это очень большой плюс к скорости, но ими сложнее добиться отказоустойчевости как у разных процессов. С разными доменами вообще не эксперементировал.
Здравствуйте, Neud, Вы писали:
N>Добрый день всем!
N>У меня несколько "нубовский" вопрос по .Net Я думаю, что почти каждый из вас видел Google Chrome browser. И как вы уже знаете, что каждая вкладка у это веб броузера в отдельном процессе. Как я понял, это сделано для того, что бы если одна вкладка повисла — она не потянет полностью все приложение. Так вот вопрос в том, что — почему они сделали именно так? Ведь многопоточностью можно достичь, по сути, такого же результата?
Возможно это сделано для безопасности, чтобы одна вкладка не могла нагадить другой.
Re[2]: Процессы vs. потоки vs. домены
От:
Аноним
Дата:
31.10.11 19:47
Оценка:
Здравствуйте, hotdox, Вы писали:
H>Возможно это сделано для безопасности, чтобы одна вкладка не могла нагадить другой.
Да, все процессы, в которых обрабатываются страницы, по своей сути являются песочницами с минимальными правами, так что даже если деструктивный код и вырвется на свободу, операционная система не даст сделать ничего плохого.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, hotdox, Вы писали:
H>>Возможно это сделано для безопасности, чтобы одна вкладка не могла нагадить другой.
А>Да, все процессы, в которых обрабатываются страницы, по своей сути являются песочницами с минимальными правами, так что даже если деструктивный код и вырвется на свободу, операционная система не даст сделать ничего плохого.
Т.е. по сути в обычном толстом клиенте такую реализацию не стоит делать, как разбивание по процессам?
Здравствуйте, Neud, Вы писали:
N>Добрый день всем!
N>У меня несколько "нубовский" вопрос по .Net Я думаю, что почти каждый из вас видел Google Chrome browser. И как вы уже знаете, что каждая вкладка у это веб броузера в отдельном процессе. Как я понял, это сделано для того, что бы если одна вкладка повисла — она не потянет полностью все приложение. Так вот вопрос в том, что — почему они сделали именно так? Ведь многопоточностью можно достичь, по сути, такого же результата?
Нельзя, chrome написан на неуправляемом языке (С++) поэтому ошибка может уронить браузер. Выгодно разделять вкладки по процессам.
N>Когда я гуглил по поводу имплементации такого плана приложения (вкладка — процесс) я наткнулся на советы, что лучше делать это через домены приложения. Типа одна вкладка — один домен.
.NET процессы, запуская только безопасный код, могут максимум уронить только домен приложения поэтому архитектура с одним процессом и разными доменами там работает. Но если надо вызывать неуправляемый код, то полюбому нужны разные процессы.
N>Так вот вопрос, кто-нибудь уже проектировал и делал такие приложения, которые предусматривают отказоустойчевость, если хотя бы один элемент повис? И какие плюсы и минусы а) разных доменов б) разных процессов в) разных потоков?
В .NET 4 необработанное исключение в потоке вызывает завершение домена приложения, поэтому если груpить недоверенный код, то только в отдельный домен.
Разные процессы — кросс-процессный маршалинг — дорого. Межу доменами должно получше работать.
Здравствуйте, gandjustas, Вы писали:
G>В .NET 4 необработанное исключение в потоке вызывает завершение домена приложения, поэтому если груpить недоверенный код, то только в отдельный домен.
Здравствуйте, MozgC, Вы писали:
MC>Здравствуйте, gandjustas, Вы писали:
G>>В .NET 4 необработанное исключение в потоке вызывает завершение домена приложения, поэтому если груpить недоверенный код, то только в отдельный домен.
MC>А что мешает обернуть функцию потока в try-catch?
То что недоверенный код сам может создать поток, да и try-catch не панацея.
Здравствуйте, Neud, Вы писали: N>У меня несколько "нубовский" вопрос по .Net Я думаю, что почти каждый из вас видел Google Chrome browser. И как вы уже знаете, что каждая вкладка у это веб броузера в отдельном процессе. Как я понял, это сделано для того, что бы если одна вкладка повисла — она не потянет полностью все приложение. Так вот вопрос в том, что — почему они сделали именно так? Ведь многопоточностью можно достичь, по сути, такого же результата?
в firefox так и сделано. в коряво написанном многопоточном приложении потоки могут влиять друг на друга. при аварийном завершении потока у нас будут мемори лики все равно. firefox это все наглядно показывает
Здравствуйте, __kot2, Вы писали:
__>Здравствуйте, Neud, Вы писали: N>>У меня несколько "нубовский" вопрос по .Net Я думаю, что почти каждый из вас видел Google Chrome browser. И как вы уже знаете, что каждая вкладка у это веб броузера в отдельном процессе. Как я понял, это сделано для того, что бы если одна вкладка повисла — она не потянет полностью все приложение. Так вот вопрос в том, что — почему они сделали именно так? Ведь многопоточностью можно достичь, по сути, такого же результата? __>в firefox так и сделано. в коряво написанном многопоточном приложении потоки могут влиять друг на друга. при аварийном завершении потока у нас будут мемори лики все равно. firefox это все наглядно показывает
Спасибо. После всего прочитанного здесь буду курить про домены приложения.
Re: Процессы vs. потоки vs. домены
От:
Аноним
Дата:
06.11.11 03:53
Оценка:
Здравствуйте, Neud, Вы писали:
N>Добрый день всем!
N>Когда я гуглил по поводу имплементации такого плана приложения (вкладка — процесс) я наткнулся на советы, что лучше делать это через домены приложения. Типа одна вкладка — один домен.
Изоляция в домене не спасет процесс от аварийного завершения в двух, мне известных, случаях:
Любое необработанное исключение
catch{} некоторых исключений
Поэтому стремный код лучше изолировать в отдельном процессе.
N>Спасибо.
Re[2]: Процессы vs. потоки vs. домены
От:
Аноним
Дата:
07.11.11 06:06
Оценка:
Здравствуйте, gandjustas, Вы писали:
N>>Когда я гуглил по поводу имплементации такого плана приложения (вкладка — процесс) я наткнулся на советы, что лучше делать это через домены приложения. Типа одна вкладка — один домен. G>.NET процессы, запуская только безопасный код, могут максимум уронить только домен приложения поэтому архитектура с одним процессом и разными доменами там работает.
это как? разве один процесс может принадлежать более чем одному домену? примеры можешь привести
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, gandjustas, Вы писали:
N>>>Когда я гуглил по поводу имплементации такого плана приложения (вкладка — процесс) я наткнулся на советы, что лучше делать это через домены приложения. Типа одна вкладка — один домен. G>>.NET процессы, запуская только безопасный код, могут максимум уронить только домен приложения поэтому архитектура с одним процессом и разными доменами там работает.
А>это как? разве один процесс может принадлежать более чем одному домену? примеры можешь привести
Вообще-то в одном процессе может быть много доменов. Пример — w3wp.exe
G>В .NET 4 необработанное исключение в потоке вызывает завершение домена приложения, поэтому если груpить недоверенный код, то только в отдельный домен.
То есть Вы хотите сказать, что необработанное исключение в отдельном домене, приведет только к выгрузке этого домена?
Здравствуйте, Neud, Вы писали:
N>Добрый день всем!
N>У меня несколько "нубовский" вопрос по .Net Я думаю, что почти каждый из вас видел Google Chrome browser. И как вы уже знаете, что каждая вкладка у это веб броузера в отдельном процессе. Как я понял, это сделано для того, что бы если одна вкладка повисла — она не потянет полностью все приложение. Так вот вопрос в том, что — почему они сделали именно так? Ведь многопоточностью можно достичь, по сути, такого же результата?
N>Когда я гуглил по поводу имплементации такого плана приложения (вкладка — процесс) я наткнулся на советы, что лучше делать это через домены приложения. Типа одна вкладка — один домен.
N>Так вот вопрос, кто-нибудь уже проектировал и делал такие приложения, которые предусматривают отказоустойчевость, если хотя бы один элемент повис? И какие плюсы и минусы а) разных доменов б) разных процессов в) разных потоков?
N>Как по мне видится, что разные потоки — это очень большой плюс к скорости, но ими сложнее добиться отказоустойчевости как у разных процессов. С разными доменами вообще не эксперементировал.
Никогда не делал подобного на C#, но внесу свои пять копеек:
1. У хрома разделение на процессы для их изоляции друг от друга (эксплоиты/ошибки портившие память) и работы их в разных контекста безопасности (потоки так могут, но это не являеться безопасным). Основная идея такого — безопасность, а не отказоустойчивость. На "повисла" это не влияет никак, что в многопоточном, что в многопроцессорным за этим надо следить примерно одинаково.
2. У винды есть такая штука как Recovery Manager. Может выдели как падает ворд или эксель? Выводят окошко "сохранения документа", сохраняют и перезапускаються. Рекомендую присмотреться именно к этому api для отказоустойчивости. Не уверен правда, что оно доступно через дотнет, возможно потребуется маршалинг.
3. По отношению к аксиоме о отказоустойчивости многопоточного и многопроцессорного приложения. Не надо путать неуправляемый и управляемый код. Ключевая разница — это обшая память. В языках с неуправляемым кодом и указателями это означает, что из за ошибки в одном потоке может быь повреждена память используемая другим — и программа рухнет как карточный домик. При грамотном подходе достичь подобного эффекта с управляемым кодом (ваш .Net) мягко скажем трудно. Поэтому разницы между C# и многопоточность / C# и многопроцессорность / C++и мнопроцесорность не будет.
Здравствуйте, 11molniev, Вы писали:
1>Здравствуйте, Neud, Вы писали:
N>>Добрый день всем!
N>>У меня несколько "нубовский" вопрос по .Net Я думаю, что почти каждый из вас видел Google Chrome browser. И как вы уже знаете, что каждая вкладка у это веб броузера в отдельном процессе. Как я понял, это сделано для того, что бы если одна вкладка повисла — она не потянет полностью все приложение. Так вот вопрос в том, что — почему они сделали именно так? Ведь многопоточностью можно достичь, по сути, такого же результата?
N>>Когда я гуглил по поводу имплементации такого плана приложения (вкладка — процесс) я наткнулся на советы, что лучше делать это через домены приложения. Типа одна вкладка — один домен.
N>>Так вот вопрос, кто-нибудь уже проектировал и делал такие приложения, которые предусматривают отказоустойчевость, если хотя бы один элемент повис? И какие плюсы и минусы а) разных доменов б) разных процессов в) разных потоков?
N>>Как по мне видится, что разные потоки — это очень большой плюс к скорости, но ими сложнее добиться отказоустойчевости как у разных процессов. С разными доменами вообще не эксперементировал.
1>Никогда не делал подобного на C#, но внесу свои пять копеек: 1>1. У хрома разделение на процессы для их изоляции друг от друга (эксплоиты/ошибки портившие память) и работы их в разных контекста безопасности (потоки так могут, но это не являеться безопасным). Основная идея такого — безопасность, а не отказоустойчивость. На "повисла" это не влияет никак, что в многопоточном, что в многопроцессорным за этим надо следить примерно одинаково. 1>2. У винды есть такая штука как Recovery Manager. Может выдели как падает ворд или эксель? Выводят окошко "сохранения документа", сохраняют и перезапускаються. Рекомендую присмотреться именно к этому api для отказоустойчивости. Не уверен правда, что оно доступно через дотнет, возможно потребуется маршалинг. 1>3. По отношению к аксиоме о отказоустойчивости многопоточного и многопроцессорного приложения. Не надо путать неуправляемый и управляемый код. Ключевая разница — это обшая память. В языках с неуправляемым кодом и указателями это означает, что из за ошибки в одном потоке может быь повреждена память используемая другим — и программа рухнет как карточный домик. При грамотном подходе достичь подобного эффекта с управляемым кодом (ваш .Net) мягко скажем трудно. Поэтому разницы между C# и многопоточность / C# и многопроцессорность / C++и мнопроцесорность не будет.
Здравствуйте, Neud, Вы писали:
N>У меня несколько "нубовский" вопрос по .Net Я думаю, что почти каждый из вас видел Google Chrome browser. И как вы уже знаете, что каждая вкладка у это веб броузера в отдельном процессе. Как я понял, это сделано для того, что бы если одна вкладка повисла — она не потянет полностью все приложение. Так вот вопрос в том, что — почему они сделали именно так? Ведь многопоточностью можно достичь, по сути, такого же результата?
Почему сделано именно так: это стоит посмотреть на chromium.org, там много вики страниц. Как уже сказали — в первую очередь для реализации песочниц, и что бы не падало всё и сразу, даже из-за собственных ошибок. В свете существования NPAPI — это так же критически важно, т.к. сторонние плагины едва ли так же хорошо тестируются. Кроме того в WebKit (да и как и во многих других движках) — невозможно прервать исполнение JavaScript (исполняется он в потоке рендерера — а он обычно и есть Main/UI Thread). В тоже самое время, следуя текущей архитектуре WebKit/Chromium, в одно-процессной модели, к сожалению, невозможно добиться такого же быстрого рендеринга с использованием всех вкусностей (в том числе и GPU), в основном это связано уже с проблемами интеграции в message loop. Поэтому это реально компромис. Вопросы навроде "невозможно остановить рендеринг" — это by design, и практически поздно что-либо менять. WebKit2 — тоже склонился к многопроцессной модели (WebKit2 — это старый дорбый WebKit но с нормальными C-like API и поддержкой многопроцессности из коробки). Остальные причины — это всё в основном уже последствия, и возможно требования кросс-платформенности и бог знает чего ещё. Не всё что можно реализовать в Windows можно реализовать в Linux/MacOSX и наоборот.
Как по мне использовать AppDomains в .NET — вполне нормальный способ, но только если это реально необходимо. Всё зависит от потребностей — оно может быть будет лучше и всё в одном домене делать, и этого будет достаточно. А может лучше будет и в раздельных процессах. Если все плагины вашего производства — то создавать AppDomains смысла нет.
G>В .NET 4 необработанное исключение в потоке вызывает завершение домена приложения, поэтому если груpить недоверенный код, то только в отдельный домен.
G>Разные процессы — кросс-процессный маршалинг — дорого. Межу доменами должно получше работать.
В данный момент работаю над решением похожей задачи, хочу поделиться наработками, если не прав — поправьте. Если создать отдельный домен, загрузить в него сборку, создать инстанс объекта в новом домене, а для этого объекта создать прокси класс в "дефолтном" домене (используя метод Unwrap), то при возникновении исключения в новом домене, оно так же будет возникать и в "дефолтном", что приведет к уничтожению процесса, в котором находятся оба домена. Для случая, когда мы вызываем метод через прокси все предельно просто — может помочь try{}\catch{}. Для более сложных случаев, например когда в метод, который вызываеться из прокси класса делает что-то в отдельном треде, к примеру — ThreadPool.QueueUserWorkItem(delegate {Thread.Sleep(1000); throw new Exception();}) все немного сложнее.
На данный момент нам удалось побороть "падение" процесса для таких случаев, путем добавления
" <runtime>
<!-- the following setting prevents the host from closing when an unhandled exception is thrown -->
<legacyUnhandledExceptionPolicy enabled="1" />
</runtime> "
В конфигурационный файл исполнаяемого файла, который так же передается в создаваемый домен
var setup = new AppDomainSetup {
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
ConfigurationFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Имя_исполняемого_файла.exe.config")};
Выгрузка же домена произоводиться при возникновении события UnhandledException созданного домена.
Если кто-то может подсказать более хорошее решение, буду очень благодарен.