Compartir a través de


Problemas de subprocesos del servidor en proceso

Un servidor en proceso no llama a CoInitialize, CoInitializeEx ni OleInitialize para marcar su modelo de subprocesos. En el caso de objetos basados en DLL o en proceso compatibles con subprocesos, debe establecer el modelo de subprocesos en el Registro. El modelo predeterminado cuando no se especifica un modelo de subprocesos es de un solo subproceso por proceso. Para especificar un modelo, agregue el valor threadingModel a la clave InprocServer32 en el Registro.

Los archivos DLL que admiten la creación de instancias de un objeto de clase deben implementar y exportar las funciones DllGetClassObject y DllCanUnloadNow. Cuando un cliente quiere una instancia de la clase que admite el archivo DLL, una llamada a CoGetClassObject (ya sea directamente o a través de una llamada a CoCreateInstance) llama a DllGetClassObject para obtener un puntero a su objeto de clase cuando el objeto se implementa en un archivo DLL. Por lo tanto, DllGetClassObject debe ser capaz de entregar varios objetos de clase o un único objeto seguro para subprocesos (básicamente, simplemente usando InterlockedIncrement/InterlockedDecrement en sus recuentos de referencia internos).

Como su nombre implica, se llama a DllCanUnloadNow para determinar si el archivo DLL que lo implementa está en uso, lo que permite al autor de la llamada descargarlo de forma segura si no lo está. Las llamadas a CoFreeUnusedLibraries desde cualquier subproceso siempre se enrutan a través del subproceso del apartamento principal para llamar a DllCanUnloadNow.

Al igual que otros servidores, los servidores en proceso pueden ser subprocesos únicos, subprocesos de apartamento o subprocesos libres. Cualquier cliente OLE puede usar estos servidores, independientemente del modelo de subprocesos usado por ese cliente.

Todas las combinaciones de interoperabilidad del modelo de subprocesos se permiten entre los clientes y los objetos en proceso. La interacción entre un cliente y un objeto en proceso que usa modelos de subprocesos diferentes es exactamente como la interacción entre los clientes y los servidores fuera de proceso. Para un servidor en proceso, cuando el modelo de subprocesos del cliente y el servidor en proceso difieren, COM debe interponerse entre el cliente y el objeto .

Cuando varios subprocesos de un cliente llaman simultáneamente a un objeto en proceso que admite el modelo de un solo subproceso, COM no puede permitir que los subprocesos de cliente accedan directamente a la interfaz del objeto,"el objeto no se diseñó para este acceso. En su lugar, COM debe asegurarse de que las llamadas se sincronizan y solo las realiza el subproceso de cliente que creó el objeto. Por lo tanto, COM crea el objeto en el apartamento principal del cliente y requiere que todos los demás apartamentos de cliente accedan al objeto mediante servidores proxy.

Cuando un apartamento de subproceso libre (modelo de apartamento multiproceso) en un cliente crea un servidor en proceso de subproceso de apartamento, COM pone en marcha un subproceso de modelo de apartamento "host" de un solo subproceso en el cliente. Este subproceso host creará el objeto y el puntero de interfaz se serializará de nuevo en el apartamento de subproceso libre del cliente. Del mismo modo, cuando un apartamento de un solo subproceso en un cliente de modelo de apartamento crea un servidor en proceso sin subprocesos, COM pone en marcha un subproceso de host libre (apartamento multiproceso en el que se creará el objeto y, a continuación, se serializará de nuevo en el apartamento de un único subproceso del cliente).

Nota

En general, si diseña una interfaz personalizada en un servidor en proceso, también debe proporcionar el código de serialización para que COM pueda serializar la interfaz entre los apartamentos de cliente.

 

COM ayuda a proteger el acceso a los objetos proporcionados por un archivo DLL de un solo subproceso al requerir acceso desde el mismo apartamento de cliente en el que se crearon. Además, todos los puntos de entrada dll (como DllGetClassObject y DllCanUnloadNow) y los datos globales siempre deben tener acceso al mismo apartamento. COM crea estos objetos en el apartamento principal del cliente, lo que proporciona al apartamento principal acceso directo a los punteros del objeto. Las llamadas de los otros apartamentos usan serialización interproceso para pasar del proxy al código auxiliar en el apartamento principal y, a continuación, al objeto . Esto permite que COM sincronice las llamadas al objeto . Las llamadas interthread son lentas, por lo que se recomienda que estos servidores se reescriban para admitir varios apartamentos.

Al igual que un servidor en proceso de un solo subproceso, el mismo departamento de cliente desde el que se creó debe tener acceso a un objeto proporcionado por un archivo DLL de modelo de apartamento. Sin embargo, los objetos proporcionados por este servidor se pueden crear en varios apartamentos del cliente, por lo que el servidor debe implementar sus puntos de entrada (como DllGetClassObject y DllCanUnloadNow) para uso multiproceso. Por ejemplo, si dos apartamentos de un cliente intentan crear dos instancias del objeto en proceso simultáneamente, ambos apartamentos pueden llamar a DllGetClassObject simultáneamente. DllCanUnloadNow debe escribirse para que el archivo DLL no se descargue mientras el código todavía se ejecuta en el archivo DLL.

Si el archivo DLL proporciona solo una instancia de la factoría de clases para crear todos los objetos, la implementación del generador de clases también debe diseñarse para uso multiproceso, ya que varios apartamentos cliente accederán a ella. Si el archivo DLL crea una nueva instancia del generador de clases cada vez que se llama a DllGetClassObject , el generador de clases no debe ser seguro para subprocesos.

Los objetos creados por el generador de clases no deben ser seguros para subprocesos. Una vez creado por un subproceso, siempre se accede al objeto a través de ese subproceso y todas las llamadas al objeto se sincronizan mediante COM. El apartamento del modelo de apartamento de un cliente que crea este objeto obtendrá un puntero directo al objeto . Los apartamentos cliente que son diferentes del apartamento en el que se creó el objeto deben tener acceso al objeto a través de servidores proxy. Estos servidores proxy se crean cuando el cliente serializa la interfaz entre sus apartamentos.

Cuando un valor de DLL ThreadingModel en proceso se establece en "Both", se puede crear y usar directamente un objeto proporcionado por este archivo DLL (sin un proxy) en apartamentos de cliente de un solo subproceso o multiproceso. Sin embargo, se puede utilizar directamente dentro del apartamento en el que se creó. Para asignar el objeto a cualquier otro apartamento, el objeto debe serializarse. El objeto DLL debe implementar su propia sincronización y varios apartamentos de cliente pueden acceder al mismo tiempo.

Para acelerar el rendimiento del acceso libre a los objetos DLL en proceso, COM proporciona la función CoCreateFreeThreadedMarshaler . Esta función crea un objeto de serialización sin subprocesos que se puede agregar con un objeto de servidor en proceso. Cuando un apartamento de cliente del mismo proceso necesita acceso a un objeto de otro apartamento, al agregar el serializador de subprocesos libres, el cliente proporciona al cliente un puntero directo al objeto de servidor, en lugar de a un proxy, cuando el cliente serializa la interfaz del objeto en un apartamento diferente. El cliente no necesita realizar ninguna sincronización. Esto solo funciona dentro del mismo proceso; La serialización estándar se usa para una referencia al objeto que se envía a otro proceso.

Un objeto proporcionado por un archivo DLL en proceso que solo admite subprocesos libres es un objeto de subproceso libre. Implementa su propia sincronización y se puede acceder a ella mediante varios subprocesos de cliente al mismo tiempo. Este servidor no serializa las interfaces entre subprocesos, por lo que este servidor se puede crear y usar directamente (sin un proxy) solo por apartamentos multiproceso en un cliente. Los apartamentos de un solo subproceso que lo crean tendrán acceso a él a través de un proxy.

Acceso a interfaces entre apartamentos

Elección del modelo de subprocesos

Apartamentos multiproceso

Procesos, subprocesos y apartamentos

Comunicación multiproceso y multiproceso

Apartamentos de un solo subproceso