
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.3] |
![]() |
|
Страницы: (21) « Первая ... 17 18 [19] 20 21 ( Перейти к последнему сообщению ) |
Сообщ.
#271
,
|
|
|
Цитата А кстати, как эта проблема решена в Unix ? Я помню фразу, что fork() создает копию исходного процесса. Это значит, что и стека копию. Получается тогда, что если передать указатель на переменную в стеке - это будет указатель на копию переменной в копии стека? Но это ведь не то, что предполагал программист. В Unix решено очень просто. Все описатели памяти передаются дочернему процессу. (там это список-дерево VMA)Т.е. и стек. Так ведь и получается адресное пространство. Ну и механизм COPY_ON_WRITE. (изначально страницы помечены на чтение, но при записи - выделяется физическая страница и туда копируются данные). Цитата У меня два критерия микроядра: 1) небольшое (десятки) число функций в его API, 2) все приложения, в том числе компоненты системы общаются с ядром только через этот его API (не имеют доступа к его внутренним структурам). 2 пункт - подходит для любого ядра. Идеальное микроядро ничем кроме пересылки сообщений не занимается. Но таких не знаю. На примере mach, в ядре есть планирование задач и управление памятью. Это в целях оптимизации. определение микроядра тут http://c2.com/cgi/wiki?MicroKernel Обратите внимание на ядро L4. (http://os.inf.tu-dresden.de/L4/l4doc.html) пишут, что только 7 API функций. Хотя здесь перечисленно больше http://os.inf.tu-dresden.de/L4/l4man.html (но 7 - это IPC) Тоже считаю, что на принцип идти не стоит. Лучше делать то, что может существовать. |
Сообщ.
#272
,
|
|
|
В-общем, в Unix ситуация специфична: каждый поток работает в своем адресном пространстве, поэтому там другие проблемы. Как выкручиваться в поддержкой Unix-приложений - можно решить позже.
Предлагаю всем желающим высказать мнение об API ядра в виде да/нет по тезисам (чтобы понять степень пересечения мнений): 1. Потоки одного процесса имеют одно адресное пространство (без копирования). 2. С каждым ключом может быть связан один обработчик. Назовем его портом, как в mach. 3. Для каждого порта может быть запущено произвольное количество потоков. 4. Планирование времени ведется в два уровня: сначала по потокам, затем внутри потоков. 5. Потоки могут создаваться извне процесса. 6. Процесс сам определяет на какие виртуальные адреса монтировать память. 7. Любое отображение памяти на виртуальное пространства производится только по явному запросу процесса. 8. Секции памяти позволяют использовать все возможности сегментной адресации (если она поддерживается платформой). 9. Сообщения могут как ставиться в очередь, так и запускать отдельный поток обработки. 10. Сообщения - единственный механизм создания потока. 11. Реализовано 5 способов отправки сообщений. 12. Секция стека формально одна на процесс, но для каждого потока выделяется отдельная физическая память. Все эти тезисы объяснялись в текстах, поэтому здесь формулировки краткие. |
Сообщ.
#273
,
|
|
|
Функция fork() (POSIX) клонирует процесс и не создаёт новых тредов в текущем процессе.
В целях оптимизации, она использует механизм COPY_ON_WRITE. (см. http://www.opengroup.org/onlinepubs/7908799/xsh/fork.html) Для создания треда в текущем процессе, в POSIX существует стандартный набор ф-ций. (см. http://www.opengroup.org/onlinepubs/7908799/xsh/threads.html) pthread_create(attr) - создаёт тред с атрибутами attr (см. http://www.opengroup.org/onlinepubs/7908799/xsh/pthread_create.html) pthread_attr_setstackaddr(attr, stackaddr) - устанавливает адрес стека в атрибутах attr (см. http://www.opengroup.org/onlinepubs/7908799/xsh/pthread_attr_setstackaddr.html) pthread_attr_setstacksize(attr, stacksize) - устанавливает размер стека в атрибутах attr (см. http://www.opengroup.org/onlinepubs/7908799/xsh/pthread_attr_setstacksize.html) Интерфейсы POSIX не являются интерфейсами ядра, но являются надстройкой над ним. |
Сообщ.
#274
,
|
|
|
2справочная . Thnx.
Цитата 1. Потоки одного процесса имеют одно адресное пространство (без копирования). Да. Цитата 2. С каждым ключом может быть связан один обработчик. Назовем его портом, как в mach. Да. Цитата 3. Для каждого порта может быть запущено произвольное количество потоков. Да. (произвольное количество запросов.) Цитата 4. Планирование времени ведется в два уровня: сначала по потокам, затем внутри потоков. не до конца понял что имелось в виду. Цитата 5. Потоки могут создаваться извне процесса. нет. (Или зачем?) Цитата 6. Процесс сам определяет на какие виртуальные адреса монтировать память. Нет. Определяет загрузчик. (А ниже только объект менеджера памяти) Цитата 7. Любое отображение памяти на виртуальное пространства производится только по явному запросу процесса. Да. (а что имеется в виду под неявным запросом процесса на память.) Цитата 8. Секции памяти позволяют использовать все возможности сегментной адресации (если она поддерживается платформой). не вижу необходимости. Могут быть осложнения. Но это не категорическое НЕТ. Цитата 9. Сообщения могут как ставиться в очередь, так и запускать отдельный поток обработки. Думаю стоит выбрать только одно. Или только очередь (один поток на интерфейс), или нет очереди, но наждой задаче новый поток(если нужна очередь, можно в процессе ставить в свою очередь - собирать из всех пришедших). Цитата 10. Сообщения - единственный механизм создания потока. Если реализуем создание процессов-потоков в отдельном объкете, то Да. Но стоит ли так усложнять. syscall (как в mach или L4) Цитата 11. Реализовано 5 способов отправки сообщений. Какие имеются в виду? Цитата 12. Секция стека формально одна на процесс, но для каждого потока выделяется отдельная физическая память. Да. Но только давайте не будем выделять по секцию отдельный тип-объект. Это просто описатели памяти. |
Сообщ.
#275
,
|
|
|
Давайте остановимся на подробном обсуждении IPC.
1) Отсылка сообщений 2) передача параметров 3) результат - отправка, получения 4) поддержка ядром асинхронных вызовов (нужны ли они в ядре? Как реализовать?) 5) учесть особенности сообщений в прерываниях. 6) из этого получим API ядра. Мне не очень нравится, если делать очередью, точнее отдельно вызывать ReсieveMessage. Лучше сделать как вызовы удаленных процедур. Создавая поток на каждое сообщение - трудности с возвратом результата. Это надо продумать. |
Сообщ.
#276
,
|
|
|
Цитата rcz, 08.10.03, 13:26:20 4. не до конца понял что имелось в виду. Это уже обсуждали: то, что запуск любого числа потоков в некотором процессе нисколько не замедляет остальные процессы. ..Хотя это можно включить потом, а для начала планировщик можно сделать самым простым. Цитата нет. (Или зачем?) Иначе физически не возможны сообщения в форме вызовов - останутся только с очередью через GetMessage. Это жестко связанные вопросы (5,9,11). Цитата 6. Нет. Определяет загрузчик. (А ниже только объект менеджера памяти) Если "нет", то и на следующий вопрос "нет". Пожалуй, нужно уточнить вопрос. Разумеется, что приложение-загрузчик изначально конфигурирует адресное пространство создаваемой задачи. Тезис такой 6. Приложение имеет возможность произвольно перекраивать свой виртуальный образ памяти, без всяких ограничений. Цитата 7. Да. (а что имеется в виду под неявным запросом процесса на память.) Неявный запрос - когда одно приложение запросило у другого большой объем данных. На что задача-сервер расшаривает свой буфер с данными. Но этот буфер не проецируется в адресное пространство клиента, пока тот не вызовет allocate, указав на какие адреса этот буфер проецировать. Цитата 8. не вижу необходимости. Могут быть осложнения. Но это не категорическое НЕТ. В любом случае - это не "предмет первой необходимости", так что для начала пусть не реализовывается. Цитата 9. Думаю стоит выбрать только одно. В известных системах как раз и выбрано что-то одно. Очередь не может обеспечить оперативность. Отдельные потоки включают все возможности очереди, но на порядок "дороже в эксплуатации". Надо бы и то и другое - это довольно нетрудно реализовать. Цитата ОК, вопрос сводится к предыдущему.10. Если реализуем создание процессов-потоков в отдельном объкете, то Да. Цитата 11. Какие имеются в виду? См. бюллетень::функции ядра. Цитата Да. Но только давайте не будем выделять по секцию отдельный тип-объект. Это просто описатели памяти. Да, секция - это описатель памяти. Но, во-вторых, это не я предложил термин секция, а кто-то в форуме. И, во-первых, ядру и приложениям в любом случае нужны разные описатели. То, что я назвал дескриптором секции - это описатель памяти на уровне приложения. А VMA содержат техническую информацию, большей частью которой может пользоваться только ядро. Это сущности разных уровней абстракции. Вроде бы очевидно, что их нужно разнести в разные структуры. |
Сообщ.
#277
,
|
|
|
Цитата rcz, 08.10.03, 13:31:54 Давайте остановимся на подробном обсуждении IPC. 1) Отсылка сообщений Сама отсылка не составляет проблемы - лишь бы решить, сколько их будет типов. Цитата 2) передача параметров Модель протоколов, как в Интернете. Сообщение имеет стандартный заголовок и облать данных, формат которой (протокол следующего уровня) определяется интерфейсом сервера. Некоторые интерфейсы серверов стандартизуются системой. Технически сообщение при отправке целиком помещается в стек. Вообще любой выход процесса "во внешний мир" (даже обращения к системе) производятся единственным образом: в стек помещаем сообщение и делаем syscall (без параметров). В конце сообщения (на вершине стека) лежит его длина, что защищает от ощибок стека. Цитата 3) результат - отправка, получения Получение сообщений я подробно описывал: "При обработке. Если это первая группа, то создается поток (карта памяти одна на весь просцесс, только стек новый), в стек которого помещается сообщение. Обработчик удалает сообщение и в стек помещает ответ, после чего командует возврат (завершение потока). Сообщений второй группы ядро, без ведома получателя, сразу копирует в его очередь, откуда их получатель может считать после, из любого своего потока. " Цитата 4) поддержка ядром асинхронных вызовов (нужны ли они в ядре? Как реализовать?) Имеется в виду многопроцессорная архитектура??? С ней лучше пока не связываться... А при одном процессоре просто некому делать такие вызовы (кроме прерываний). Цитата 5) учесть особенности сообщений в прерываниях. Мне не очень нравится, если делать очередью, точнее отдельно вызывать ReсieveMessage. Лучше сделать как вызовы удаленных процедур. Создавая поток на каждое сообщение - трудности с возвратом результата. Это надо продумать. В пяти предложенных типах сообщений предусмотрены все эти моменты. Прерывания - без особенностей реализуются через ForkMessage. Вызовы удаленных процедур - RunMessage. Возврат результата: если поток отправителя ждал, то ответ он получит тут же в стеке; если отправка была без ожидания - ответ придет отдельным сообщением (типа Post). |
Сообщ.
#278
,
|
|
|
Цитата Это уже обсуждали: то, что запуск любого числа потоков в некотором процессе нисколько не замедляет остальные процессы. Можно поэкспеременитирвать. Это не сложно реализуется Цитата 6. Приложение имеет возможность произвольно перекраивать свой виртуальный образ памяти, без всяких ограничений. Да. 7. Да Цитата В известных системах как раз и выбрано что-то одно. Очередь не может обеспечить оперативность. Отдельные потоки включают все возможности очереди, но на порядок "дороже в эксплуатации". Надо бы и то и другое - это довольно нетрудно реализовать. Реализовать то нетрудно, но употребить. И не испортит ли это архитектуру. Цитата Имеется в виду многопроцессорная архитектура С ней лучше пока не связываться... Нет. однопроцессорная система. Просто вопрос. Реализовывать ли поддержку асинхронности в ядре. Или пользователь будет для асинхронных вызовов сам создавать потоки. Цитата 12. Секция стека формально одна на процесс, но для каждого потока выделяется отдельная физическая память. НЕТ. Не будем нагромождать поток описанием памяти. Потокам нужен доступ к стеку родителей.(поддержка передачи указателей на стековые данные). И стек - те же VMA, что и остальная память. |
Сообщ.
#279
,
|
|
|
Цитата rcz, 08.10.03, 22:46:50 Реализовать то нетрудно, но употребить. И не испортит ли это архитектуру. Очереди сообщений может и портят архитектуру. Но уж слишком они повышают эффективность.. Цитата Нет. однопроцессорная система. Просто вопрос. Реализовывать ли поддержку асинхронности в ядре. Или пользователь будет для асинхронных вызовов сам создавать потоки. Ядро все операции исполняет быстро. И даже если б были медленные функции, все равно обращения к ядру стоит делать все синхронными. По крайней мере в первой версии. Потом, если будет видна сильная необходимость (что маловероятно) - пересмотреть. Цитата НЕТ. Не будем нагромождать поток описанием памяти. Потокам нужен доступ к стеку родителей.(поддержка передачи указателей на стековые данные). И стек - те же VMA, что и остальная память. Тогда придумайте, как решить запускать новые потоки для обработки сообщений. Такой поток создается не самим приложением, но только само приложение может дать виртуальное пространство новому стеку. Эту проблему я и решал усложнением секций стека. Идея в том, что стек может иметь "слои" (как изображение), и для нового потока уже в имеющейся секции создается новый слой. Для передачи указателей на переменные в стеке поток должен отобразить свой стек в новую "неслоистую" секцию и переключить указатель стека на нее. Проблему это решает. Конечно, пришлось ввести новое понятие "слоев", что минус, но он один. А как бы Вы решали описанную проблему? |
Сообщ.
#280
,
|
|
|
Цитата Очереди сообщений может и портят архитектуру. Но уж слишком они повышают эффективность.. Вроде я никогда не был против очередей. Просто я считаю, что все надо как-то обобщить, чтоб не рассматривать множество деталей. Цитата Ядро все операции исполняет быстро. И даже если б были медленные функции, все равно обращения к ядру стоит делать все синхронными. По крайней мере в первой версии. Потом, если будет видна сильная необходимость (что маловероятно) - пересмотреть. Я не ядро имел в виду. А ожидение завершение выполнения метода интерфейса вызвавшим потоком. Цитата Тогда придумайте, как решить запускать новые потоки для обработки сообщений. Такой поток создается не самим приложением, но только само приложение может дать виртуальное пространство новому стеку. Эту проблему я и решал усложнением секций стека. Идея в том, что стек может иметь "слои" (как изображение), и для нового потока уже в имеющейся секции создается новый слой. Для передачи указателей на переменные в стеке поток должен отобразить свой стек в новую "неслоистую" секцию и переключить указатель стека на нее. Проблему это решает. Конечно, пришлось ввести новое понятие "слоев", что минус, но он один. А как бы Вы решали описанную проблему? Я уже писал вариант обработки сообщения. Основанный на очереди и с поддержкой асинхронности. Примерно так. 1)Некий объект регистрирует свой интерфейс, говоря тем, что готов принимать сообщения (удаленные вызовы). Этим он создает поток (как писал с автосбросом) обработчик, он спит. 2) Приложения, которые хотят вызвать что-то из интерфейса, посылают ему сообщения. Эти сообщения ставятся в очередь и передаются этому потоку обработчику. Обработчик волен создавать для каждого сообщения новый поток и возвращать управление. Поток обработчик не вызывает GetMessage, ядро его просто с каждым сообщением пробуждает. 3) созданный поток (если его не, то сам обработчик) возвращает результат. Данный метод позволяет: 1 - не мучаться отдельно со стеками 2 - поток создается внутри. 3 - позволяет инкапсулировать способ обработки сообщений. Асинхронность реализовать можно в самом ядре. При отсылки сообщения обработчику не дожидаться его завершения. Минусы: 1 - реализуется только с очередями. 2 - если учитывать асинхронность на уровне ядра, не придумал унифицированного способа возврата результата. Но не исключаю, что просто реализовать Добавьте свои минусы и плюсы к этой системе. |
Сообщ.
#281
,
|
|
|
Цитата rcz, 09.10.03, 12:01:56 Я не ядро имел в виду. А ожидение завершение выполнения метода интерфейса вызвавшим потоком. Такой вопрос может возникнуть только если Вы несогласны с предложенными 5-ю типами сообщений (потому что если их принять, то вопрос отпадает: ядро обеспечиывет и синхонные и асинхроггые сообщения). Но если несогласны, сначала скажите в чем. Цитата Данный метод позволяет: ... 2 - поток создается внутри. С моей точки зрения это вовсе не плюс, а минус. Так как этот способ позволяет лишь приближенно сымитировать функциональный вызов, но не в-точности. ..Но этот аргумент я уже приводил - так что по данному вопросу, видимо, каждый останется при своем мнении.. Цитата Асинхронность реализовать можно в самом ядре. При отсылки сообщения обработчику не дожидаться его завершения. Само собой.. Цитата Минусы: ... 2 - если учитывать асинхронность на уровне ядра, не придумал унифицированного способа возврата результата. Но не исключаю, что просто реализовать Для асинхронных сообщений (post) возврат результата и не нужен. Вернее, для ответа просто посылается новое сообщение. Так что это не минус. Цитата Добавьте свои минусы и плюсы к этой системе. Самый большой минус. 3. Требуется один дополнительный тред и одна дополнительная очередь сообщений. То есть, обработчик будет вынужден создать, как минимум, два треда и две очереди сообщений: одна для приходящих сообщений - а во вторую придется после сортировки копировать асинхронные сообщения, для последующей обработки. Если же сообщения, для которых не создается специальный тред, сразу обрабатывать в принимающем потоке, то не обеспечивается оперативность реакции на срочные сообщения (в т.ч. прерывания). 4. Так уже сделано, хоть в тех же виндах. А при прочих равных интереснее реализовывать то, чего еще не делалось. |
Сообщ.
#282
,
|
|
|
Цитата 3. Требуется один дополнительный тред и одна дополнительная очередь сообщений. То есть, обработчик будет вынужден создать, как минимум, два треда и две очереди сообщений: одна для приходящих сообщений - а во вторую придется после сортировки копировать асинхронные сообщения, для последующей обработки. Ну если учесть, что в вашем случае для каждого сообщения надо создавать по потоку тем более из-вне процесса (нарушение инкапсуляции и т.п.), то какой-то один поток, тем более спящий, не мешает. А если интрефей не поддерживает асинхронности(точнее он не реентерабельный), то обработчик может не создавать поток. Ну и быстрее простое переключение на новый поток, чем его создание - в случае, что для каждого сооющения ядро создает поток. А зачем создавать "мимнимум 2 треда и 2 очереди сообщений". Нужна только 1 очередь со стороны ядра, а тот тред никаких очередей не делает. Асинхронные сообщения отправляются как сообщения-отправителю (тот в этих целях может сделать call-back обработчик). По-моему удобно и хоть как-то структурированно. Цитата Так уже сделано, хоть в тех же виндах. А при прочих равных интереснее реализовывать то, чего еще не делалось. Если так подходить к делу, то вообще ничего не реализуешь, потому, что каждая идея была как-то реализована, а если не реализована - то это или плохая идея, или очень сложно реализовать, или эффективность будет ужасная. P.S.Сами просили Цитата Я и привел пример системы.Тогда придумайте, как решить запускать новые потоки для обработки сообщений. Такой поток создается не самим приложением, но только само приложение может дать виртуальное пространство новому стеку. |
Сообщ.
#283
,
|
|
|
Цитата rcz, 09.10.03, 17:37:37 Ну если учесть, что в вашем случае для каждого сообщения надо создавать по потоку Почему для каждого?! Все зависит от типа сообщения. Разница только в том, что я предлагаю использовать две схемы, а Вы - оставить одну. Цитата тем более из-вне процесса (нарушение инкапсуляции и т.п.) По-вашему получается, что любой асинхронный (из другого потока) вызов метода класса является нарушением инкапсуляции. Создание потока извне процесса это не более, чем реализация межзадачного вызова функции. Цитата Ну и быстрее простое переключение на новый поток, чем его создание - в случае, что для каждого сооющения ядро создает поток. Стоимость создания потока примерно равна стоимости выделения одной страницы памяти, что немного. Цитата А зачем создавать "мимнимум 2 треда и 2 очереди сообщений". Нужна только 1 очередь со стороны ядра, а тот тред никаких очередей не делает. Тогда объясните, как Вы сможете гарантировать, что приоритетные сообщения (напр. реального времени) будут обработаны немедленно (не ожидая, пока сервер закончит обработку предыдущего сообщения) ? Цитата Поток обработчик не вызывает GetMessage, ядро его просто с каждым сообщением пробуждает. Так ведь GetMessage и есть syscall для засыпания потока. А пробуждаясь, он все равно должен получить сообщение, поэтому других специальных функций засыпания и не нужно. |
Сообщ.
#284
,
|
|
|
Ладно.
Цитата Так ведь GetMessage и есть syscall для засыпания потока. А пробуждаясь, он все равно должен получить сообщение, поэтому других специальных функций засыпания и не нужно. Я хотел избавится от лишнего syscall'a. И этот метод - считай GetMessage, только без явного его использования. А других функций засыпания и не будет. Цитата По-вашему получается, что любой асинхронный (из другого потока) вызов метода класса является нарушением инкапсуляции. С чего это взяли? Это вызов метода интерфейса. Асинхронный - это только лишь отсутствие ожидания завершения обработки. Цитата Создание потока извне процесса это не более, чем реализация межзадачного вызова функции. И является нарушением микроядерной архитектуры. Система обработки сообщений (межзадачный вызов) изначально может ничего не знать о создании потоков (это другой объект, они не связаны). Точнее о деталях создания (стек - очень хорошая деталь) Цитата Тогда объясните, как Вы сможете гарантировать, что приоритетные сообщения (напр. реального времени) будут обработаны немедленно (не ожидая, пока сервер закончит обработку предыдущего сообщения) ? Что ж. Это недостаток. Но тогда скажите как в вашей системе смогут обработаться 2 сообщения приоритета реального времени одновременно? ![]() В моем случае интерфейс создает сам поток. И задержка обработки более приоритетного сообщения - время создание потока. Но в моем случае есть возможность сделать,что интерфейс обрабатывает только один запрос за время (нет задержек на создание потока). В Вашем - ядро создает поток, задержка та же. А еще, кстати, надо рассмотреть такую ситуацию. Приходят 2 сообщения. (у второго приоритет выше). Первое сообщение начинает выполняться, дле него создается поток, с приоритетом выше, чем у потока, отправивешего 2-е сообщение. Значит 2-е сообщение(приоритет будет реалтайм) не начнет выполняться, будет ждать. Эта ситуация грозит в обоих вариантах (правда если делать очередь в ядре, то оно может отсортировать, хотя это не спасет от всех случаев). Real-Time не получается. P.S. Мое дело предложить вариант. Ваше дело отказаться. Настаивать не буду. А в варианте создания потока для каждого сообщения - о расположении стека не стоит волноваться. Можно сделать так. При регистрации интерфейса указывается размер стека,адрес функции(ну и доп..инфа.для создания потоков). Неявным образом задается адресное пространство - процесс. Создание потоков - одна функция на системы. При появлении сообщения, ядро просто обычный образом создает поток, как это бы делал сам процесс(параметры были переданы при объявлении интерфейса). И передает ему параметры (сообщение). Это получается отложенное создание потока процессом Цитата Просто интересно. А Где ? 4. Так уже сделано, хоть в тех же виндах. |
Сообщ.
#285
,
|
|
|
Цитата rcz, 09.10.03, 23:29:35 Что ж. Это недостаток. Но тогда скажите как в вашей системе смогут обработаться 2 сообщения приоритета реального времени одновременно? ![]() Нет проблем. В двух параллельных потоках. Цитата В моем случае интерфейс создает сам поток. И задержка обработки более приоритетного сообщения - время создание потока. Эта задержка невелика и неизбежна. А серьезная задержка будет в том, что придется ждать завершения обработки предыдущего сообщения. А это может быть очень долго. Потому что у вас ядро может лишь обеспечить сообщению первое место в очереди - но прерывать уже начавшуюся обработку предыдущего сообщения оно не может. Единственный способ обеспечить немедленную обработку в Вашей схеме - это если поток обработки будет только сортировать сообщения: для срочных запускать новый поток, несрочные - перемещать в новую очередь. Цитата Но в моем случае есть возможность сделать,что интерфейс обрабатывает только один запрос за время (нет задержек на создание потока). Но я этот вариант тоже включаю. Цитата P.S. Мое дело предложить вариант. Ваше дело отказаться. Настаивать не буду. Это как раз не я отказываюсь. Я то предлагаю и Вашу схему в том числе, но вместе с ней еще дополнительную. Предлагаю такой компромисс: включить в дизайн оба варианта, но там где сложно ставить "заглушки". Цитата Просто интересно. А Где ? Ну как где. WM_COPY_DATA. Оно, конечно, косячно, и только в синхронном варианте, и без приоритетов - но по сути то же. |