2012-02-25 6 views
10

La biblioteca C de GNU utiliza desenrollado DWARF2 para la cancelación de subprocesos actualmente, de modo que las excepciones C++ y los controladores de cancelación de pthread se invocan a través de un proceso de desenrollado de marco de llamada común que invoca destructores para objetos automáticos según sea necesario en el camino. Sin embargo, hasta donde puedo decir, todavía no existe un estándar que especifique la interacción entre los hilos (POSIX) y C++, y presumiblemente una aplicación que desee ser portable debería suponer que lanzar excepciones fuera de contextos de limpieza de cancelación es tan indefinido como llamar al longjmp de ellos, y que la cancelación de un hilo que tiene objetos automáticos activos con destructores no triviales también es un comportamiento indefinido.¿Hay algún movimiento hacia la especificación de la interacción de las excepciones de C++ y la cancelación de pthread?

¿Existe algún proceso de estandarización en curso que aborde esta interacción, o es algo que se puede esperar que esté indefinido en el futuro? ¿C++ 11 tiene alguna noción análoga a la cancelación de subprocesos POSIX en su soporte de subprocesos?

+5

Imagino que se supone que debes usar '' en C++ 11 y no en Posix ... entonces tienes punteros de excepción y todo eso para controlar la propagación de excepciones. –

+2

¿Tiene '' un análogo a la cancelación de subprocesos POSIX? Parece que sería difícil especificar ya que todo el punto de la cancelación de subprocesos POSIX es la forma en que interactúa con las funciones POSIX que podrían bloquear el avance del subproceso durante un tiempo significativo o ilimitado. –

+0

Buena pregunta; no hay nada en el estándar sobre la cancelación, y por lo tanto, supongo que no existe un mecanismo estándar para la interacción con los hilos de Posix. ¿Necesitas cancelación en absoluto, sin embargo? Si reconsideras tu solución en C++, ¿no hay más forma idiomática? –

Respuesta

13

Como alguien que se sienta en ISO/IEC SC22 que incluye WG14 (C), WG15 (POSIX) y WG21 (C++), puedo decirle que la respuesta rápida es no, las excepciones C++ y la cancelación de subprocesos no van a nos vemos pronto. C11 y C++ 11 no hacen mención de la cancelación de subprocesos, y son altamente, si no extremadamente improbables, para reconocerlo antes de la próxima versión de los principales estándares en unos diez años.

La respuesta más larga se reduce a cómo funcionan los estándares. Básicamente ISO solo puede estandarizar lo que todos pueden llegar a acordar, y las personas no están de acuerdo cuando se trata de la cancelación de subprocesos. La idea de que un hilo de ejecución tenga que volcar el estado antes de cada llamada al sistema cancelable va en contra de todo el espíritu del desarrollo de software moderno. Causa inmensos problemas para la optimización del compilador porque a diferencia de los lanzamientos de excepción C++, una cadena de caracteres se define como la llamada thread_terminate (self) que explícitamente impide hacer algo adicional (e incluso los manejadores de cancelación no son invocados confiablemente en muchas implementaciones), y No creo que los partidarios de la cancelación de temas estuvieran en desacuerdo, es una mala solución.

El problema es que la única alternativa adecuada es volver a emitir la API POSIX i/o con variantes de finalización asíncronas. Y el problema con eso es que las diferentes implementaciones de POSIX piensan en la finalización de la sincronización de manera muy diferente. Quiero decir, ni siquiera podemos llegar a un acuerdo sobre un estándar para las colas de espera del kernel, por lo tanto, hasta que eso se pueda lograr, una API de i/o asíncrona está muy lejos. Tengo una propuesta para hacer algún movimiento en las colas de espera del núcleo para las próximas normas TC/TR, pero el objeto propuesto es deliberadamente extremadamente simplista.

Lo que hemos intentado hacer en C11/C++ 11 es que la API de subprocesos siempre tenga versiones sin bloqueo: solo hay una API allí que no se puede hacer sin bloqueo, que es thread_join() (no hay thread_timedjoin()) y planeo enviar personalmente una errata sobre eso después de que tenga la aprobación del Austin Working Group. En todos los demás casos, uno siempre puede construir algo que no sea eficiente, pero que sea un programa correcto.

A largo plazo, en lo personal, veo muchas buenas razones para agregar el manejo de excepciones a C siguiendo una semántica similar a C++. No tendrías soporte de objeto necesariamente (en realidad yo apoyaría agregar objetos no virtuales a C también personalmente), pero tendrías el concepto de llamadas de función lambda desenrolladas. Eso nos permitiría formalizar hacks como la cancelación de subprocesos con un mecanismo bien definido. También hace que escribir C sea tolerante a fallas mucho más fácil y más seguro al permitirle escribir el desenrollado mientras escribe el viento, y deja que el viejo C interactúe transparentemente con el nuevo C.

En cuanto a arrojar excepciones desde el manejo de excepciones, yo personalmente creo que Necesito hacer algo mejor que simplemente invocando siempre terminate().Como el desenrollado puede causar la construcción de objetos nuevos o, de hecho, cualquier otra fuente de saltos de excepción, personalmente preferiría en gran medida si se hacen todos los intentos razonables para desenrollar toda la pila antes de finalizar el proceso.

Por lo tanto, en resumen, se espera que la cancelación de subprocesos de POSIX siga siendo vista como indefinida, y las grandes posibilidades son que a la larga se desestime a favor de algo mejor.

BTW, generalmente la cancelación de subprocesos POSIX es muy poco aplicable entre las implementaciones, por lo que cualquier código que use la cancelación de subprocesos POSIX se basa efectivamente en un comportamiento específico de plataforma que es idéntico al uso de API que no sean POSIX. Si desea que su código sea portátil, no use la cancelación de subprocesos de POSIX. En su lugar, use select() o poll() incluyendo un descriptor de archivo mágico "por favor detenga el hilo ahora". En mi propio código C++, en realidad tengo una macro contenedor de API del sistema que prueba este descriptor de archivo mágico y arroja una excepción especial de C++. Esto garantiza un comportamiento idéntico en todas las plataformas, incluido Windows.

+0

Gracias, este fue exactamente el tipo de respuesta que estaba buscando. –

+0

Por cierto, bienvenido a SO! Espero que sigas siendo parte de la comunidad. Abrí una recompensa de +500 para asignar tu respuesta una vez que el período de espera de 24 horas haya terminado. –

+0

Gracias. Para ser honesto hasta ahora, casi toda mi ayuda a los demás estaba en las listas de correo: he escrito algo así como más de 10k correos electrónicos a listas de correo de tecnología según google. Pero tengo que admitir que Google califica el stackoverflow tan alto en los resultados de búsqueda frente a todo lo demás. Probablemente he estado desperdiciando mi esfuerzo. :) –

Cuestiones relacionadas