Si realmente desea hacer algo como lo que las funciones ucontext.h
permiten, seguiría usándolas. Cualquier otra cosa será menos portátil. Marcarlos como obsoletos en POSIX parece haber sido un error horrible de pedantería por parte de alguien en el comité. POSIX en sí requiere que los punteros de función y de datos sean del mismo tamaño y que los punteros a las funciones sean representables para el void *
, y que C requiera un molde entre los tipos de puntero a la función y sea seguro para el viaje de ida y vuelta, este problema podría haber sido resuelto
Hay un problema real, que la conversión de la int argc, ...
pasado a makecontext
en una forma para pasar a la función no se puede hacer sin ayuda importante del compilador a menos que la convención de llamada para funciones variadic y no variadic pasa a ser el mismo (y aún así es bastante cuestionable si se puede hacer de manera robusta). Sin embargo, este problema podría haberse resuelto simplemente desaprobando el uso de makecontext
en cualquier forma que no sea makecontext(ucp, func, 1, (void *)arg);
.
Quizás una pregunta mejor es por qué cree que las funciones ucontext.h
son la mejor manera de manejar el enhebrado. Si desea ir con ellos, le sugiero que escriba una interfaz de contenedor que puede implementar ya sea con ucontext.h
o con pthreads, y luego comparar el rendimiento y la hinchazón. Esto también tendrá la ventaja de que, si los sistemas futuros dejan de admitir el ucontext.h
, simplemente puede pasar a la compilación con la implementación pthread y todo funcionará. (Para entonces, la hinchazón puede ser menos importante, el beneficio de varios núcleos/SMP probablemente será enorme, y es de esperar implementaciones pthread será menos hinchado.)
Editar (basado en la solicitud de OP): Para implementar "threading cooperativo" con pthreads, necesita variables de condición.He aquí una pthreads decente tutorial con información sobre el uso de ellos:
https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables
Su cooperativa multitarea primitiva de "mano de ejecución para enhebrar X" sería algo 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);
Esperanza Tengo que todos derecho; al menos la idea general es correcta. Si alguien ve errores, por favor coméntalo para que pueda solucionarlo. La mitad del bloqueo (mutex other_thread
) probablemente sea completamente innecesario con este tipo de uso, por lo que quizás pueda hacer que el mutex sea una variable local en la función task_switch
. Todo lo que realmente estaría haciendo es usar pthread_cond_wait
y pthread_cond_signal
como primitivas "ir a dormir" y "despertar otro hilo".
Estoy buscando un enhebrado cooperativo, que es lo que pthread no hace. En el enhebrado cooperativo/subprocesamiento de usuario, cada subproceso es responsable de dejar que los demás se ejecuten. Los subprocesos están programados por el sistema operativo, lo que dificulta implementar el enhebrado cooperativo. – zneak
¿Quizás estás buscando variables condicionales? https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables –
Agregó algunos detalles sobre cómo puede hacer esto con pthreads. –