thread pthread_join pthread_create pthread c posix user-thread

pthread_join - thread api in c



¿Hay algo para reemplazar las funciones<ucontext.h>? (4)

Las funciones de la hebra del usuario en <ucontext.h> están en desuso porque usan una función C en desuso ( usan una declaración de función con paréntesis vacíos para un argumento ).

¿Hay un reemplazo estándar para ellos? No creo que los subprocesos completos sean buenos para implementar subprocesos cooperativos.


Especificaciones de la base de grupo abierto número 6 IEEE Std 1003.1, edición de 2004

Todavía se muestran makecontext () y swapcontext () con la misma sintaxis en desuso. No he visto nada más reciente.


No, no hay un reemplazo estándar para ellos.

Tus opciones son

  • continúe usando <ucontext.h> aunque contengan C. obsoleta.
  • cambiar a pthreads
  • escribe tu propia biblioteca co-thread
  • use una biblioteca de co-hilos existente (y posiblemente no tan portátil) como http://swtch.com/libtask/ , aunque muchas de estas bibliotecas se implementan sobre ucontext.h

Para lo que vale, hay una biblioteca Boost.Context que fue aceptada recientemente y solo necesita fusionarse en una versión oficial de Boost. Boost.Context aborda los mismos casos de uso que la familia de ucontext POSIX: cambio de contexto cooperativo de bajo ucontext . El autor se ha tomado la molestia de los problemas de rendimiento.


Si realmente quieres hacer algo como lo que permiten las funciones ucontext.h , seguiría usándolas. Cualquier otra cosa será menos portátil. Al marcarlos como obsoletos en POSIX parece haber sido un horrible error de pedantería por parte de alguien en el comité. POSIX requiere que los punteros de función y los punteros de datos sean del mismo tamaño y para que los punteros de función puedan ser convertidos en void * , y C requiere un lanzamiento entre los tipos de punteros de función y la vuelta para que sea segura. problema podría haber sido resuelto

Hay un problema real, que convertir int argc, ... pasado a makecontext en una forma para pasar a la función no se puede hacer sin una ayuda importante del compilador a menos que la convención de llamada para funciones variadic y non-variadic sea la Lo mismo (e incluso entonces es bastante cuestionable si se puede hacer con firmeza). Sin embargo, este problema podría haberse resuelto simplemente desaprobando el uso de makecontext en cualquier otra forma que no sea makecontext(ucp, func, 1, (void *)arg); .

Sin embargo, tal vez una mejor pregunta es por qué cree que ucontext.h funciones ucontext.h son la mejor manera de manejar los hilos. Si desea ir con ellos, le sugiero que escriba una interfaz de contenedor que pueda implementar con ucontext.h o con pthreads, y luego compare el rendimiento y la cantidad. Esto también tendrá la ventaja de que, en caso de que los sistemas futuros ucontext.h soporte para ucontext.h , simplemente puede cambiar a la compilación con la implementación basada en pthread y todo funcionará. (Para entonces, la hinchazón podría ser menos importante, el beneficio de los multi-núcleos / SMP probablemente será enorme, y es de esperar que las implementaciones de subprocesos estén menos hinchadas).

Editar (según la solicitud de OP): Para implementar "subprocesos cooperativos" con pthreads, necesita variables de condición. Aquí hay un tutorial decente de pthreads con información sobre cómo usarlos:

https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables

Su primitiva de multitarea cooperativa de "ejecución remota para subprocesos X" sería algo así como:

self->flag = 0; other_thread->flag = 1; pthread_mutex_lock(other_thread->mutex); pthread_cond_signal(other_thread->cond); pthread_mutex_unlock(other_thread->mutex); pthread_mutex_lock(self->mutex); while (!self->flag) pthread_cond_wait(self->cond, self->mutex); pthread_mutex_unlock(self->mutex);

Espero haberlo hecho bien; Al menos la idea general es correcta. Si alguien ve errores, por favor comenta para que pueda arreglarlo. La mitad del bloqueo (la other_thread de otro other_thread ) probablemente sea totalmente innecesaria con este tipo de uso, por lo que quizás pueda convertir la task_switch en una variable local en la función de cambio de task_switch . Todo lo que realmente estarías haciendo es usar pthread_cond_wait y pthread_cond_signal como primitivas de "ir a dormir" y "despertar otro hilo".