Apartamentos multiproceso

En un modelo de apartamento multiproceso, todos los subprocesos del proceso que se han inicializado como subprocesos libres residen en un solo apartamento. Por lo tanto, no es necesario calcular las referencias entre subprocesos. Los subprocesos no necesitan recuperar y enviar mensajes porque COM no usa mensajes de ventana en este modelo.

Las llamadas a métodos de objetos del apartamento multiproceso se pueden ejecutar en cualquier subproceso del apartamento. No hay ninguna serialización de llamadas; es posible que se produzcan muchas llamadas al mismo método o al mismo objeto simultáneamente. Los objetos creados en el apartamento multiproceso deben poder controlar las llamadas en sus métodos desde otros subprocesos en cualquier momento.

Dado que las llamadas a objetos no se serializan de ninguna manera, la simultaneidad de objetos multiproceso ofrece el máximo rendimiento y aprovecha la mejor ventaja del hardware de varios procesadores para las llamadas entre subprocesos, entre procesos y entre máquinas. Sin embargo, esto significa que el código de los objetos debe proporcionar sincronización en sus implementaciones de interfaz, normalmente mediante el uso de primitivos de sincronización, como objetos de evento, secciones críticas, exclusión mutua o semáforos, que se describen más adelante en esta sección. Además, dado que el objeto no controla la duración de los subprocesos a los que accede, no se puede almacenar ningún estado específico del subproceso en el objeto (en el almacenamiento local del subproceso).

A continuación se muestran algunas consideraciones importantes sobre la sincronización de apartamentos multiproceso:

  • COM proporciona sincronización de llamadas solo para apartamentos de un solo subproceso.
  • Los apartamentos multiproceso no reciben llamadas mientras realizan llamadas (en el mismo subproceso).
  • Los apartamentos multiproceso no pueden realizar llamadas sincronizadas con entrada.
  • Las llamadas asincrónicas se convierten en llamadas sincrónicas en apartamentos multiproceso.
  • No se llama al filtro de mensajes para ningún subproceso en un apartamento multiproceso.

Para inicializar un subproceso como subproceso libre, llame a CoInitializeEx y especifique COINIT_MULTITHREADED. Para obtener información sobre los subprocesos del servidor en proceso, vea Problemas de subprocesos del servidor en proceso.

Varios clientes pueden llamar simultáneamente, desde diferentes subprocesos, un objeto que admite el subproceso libre. En los servidores sin subprocesos fuera de proceso, COM, a través del subsistema RPC, crea un grupo de subprocesos en el proceso de servidor y una llamada de cliente (o varias llamadas de cliente) se puede entregar en cualquiera de estos subprocesos en cualquier momento. Un servidor fuera de proceso también debe implementar la sincronización en su generador de clases. Los objetos sin subprocesos y en proceso pueden recibir llamadas directas desde varios subprocesos del cliente.

El cliente puede realizar trabajos COM en varios subprocesos. Todos los subprocesos pertenecen al mismo apartamento multiproceso. Los punteros de interfaz se pasan directamente desde el subproceso al subproceso dentro de un apartamento multiproceso, por lo que los punteros de interfaz no se serializarán entre sus subprocesos. Los filtros de mensajes (implementaciones de IMessageFilter) no se usan en apartamentos multiproceso. El subproceso de cliente se suspenderá cuando realice una llamada COM a objetos fuera de apartamento y se reanudará cuando se devuelva la llamada. Rpc sigue administrando las llamadas entre procesos.

Los subprocesos inicializados con el modelo de subproceso libre deben implementar su propia sincronización. Como se mencionó anteriormente en esta sección, Windows habilita esta implementación a través de los siguientes primitivos de sincronización:

  • Los objetos de evento proporcionan una manera de indicar uno o varios subprocesos que se ha producido un evento. Cualquier subproceso dentro de un proceso puede crear un objeto de evento. La función de creación de eventos devuelve un identificador para el evento, CreateEvent. Una vez creado un objeto de evento, los subprocesos con un identificador para el objeto pueden esperar en él antes de continuar con la ejecución.
  • Las secciones críticas se usan para una sección de código que requiere acceso exclusivo a algún conjunto de datos compartidos antes de que se pueda ejecutar y que solo los subprocesos usan dentro de un único proceso. Una sección crítica es como un punto a través del cual solo un subproceso puede pasar, trabajando de la siguiente manera:
    • Para asegurarse de que no más de un subproceso a la vez accede a los datos compartidos, el subproceso principal de un proceso asigna una estructura de datos de CRITICAL_SECTION global e inicializa sus miembros. Un subproceso que escribe una sección crítica llama a la función EnterCriticalSection y modifica los miembros de la estructura de datos.
    • Un subproceso que intenta escribir una sección crítica llama a EnterCriticalSection , que comprueba si se ha modificado la estructura de datos CRITICAL_SECTION. Si es así, otro subproceso se encuentra actualmente en la sección crítica y el subproceso posterior se pone en suspensión. Un subproceso que sale de una sección crítica llama a LeaveCriticalSection, que restablece la estructura de datos. Cuando un subproceso sale de una sección crítica, el sistema activa uno de los subprocesos en suspensión, que después entra en la sección crítica.
  • Las exclusión mutuas realizan la misma función que una sección crítica, salvo que la exclusión mutua es accesible para subprocesos que se ejecutan en diferentes procesos. Poseer un objeto de exclusión mutua es como tener el suelo en un debate. Un proceso crea un objeto de exclusión mutua llamando a la función CreateMutex , que devuelve un identificador. El primer subproceso que solicita un objeto de exclusión mutua obtiene la propiedad de él. Cuando el subproceso haya terminado con la exclusión mutua, la propiedad pasa a otros subprocesos por primera vez, primero servidos.
  • Los semáforos se usan para mantener un recuento de referencias en algunos recursos disponibles. Un subproceso crea un semáforo para un recurso llamando a la función CreateSemaphore y pasando un puntero al recurso, un recuento de recursos inicial y el número máximo de recursos. Esta función devuelve un identificador. Un subproceso que solicita un recurso pasa su identificador de semáforo en una llamada a la función WaitForSingleObject . El objeto semáforo sondea el recurso para determinar si está disponible. Si es así, el semáforo disminuye el recuento de recursos y activa el subproceso en espera. Si el recuento es cero, el subproceso permanece dormido hasta que otro subproceso libera un recurso, lo que hace que el semáforo incremente el recuento en uno.

Acceso a interfaces entre apartamentos

Elección del modelo de subprocesos

Problemas de subprocesos del servidor en proceso

Procesos, subprocesos y apartamentos

Comunicación multiproceso y multiproceso

Apartamentos de un solo subproceso