Есть ли что-то, чтобы заменить функции <ucontext.h>?
Пользовательский поток функционирует в <ucontext.h>
устарели, потому что они используют устаревшую функцию C (они используют объявление функции с пустыми скобками для аргумента).
Есть ли для них стандартная замена? Я не чувствую, что полноценные потоки хороши для реализации совместных потоков.
4 ответа
Если вы действительно хотите сделать что-то вроде того, что ucontext.h
функции позволяют, я бы продолжал использовать их. Все остальное будет менее переносимым. Помечать их как устаревшие в POSIX кажется ужасной ошибкой педантизма кем-то из членов комитета. Сам POSIX требует, чтобы указатели функций и указатели данных были одинакового размера, а указатели функций должны быть представимы в виде void *
, и сам C требует преобразования между типами указателей на функции и обратно, чтобы быть безопасным в обоих направлениях, поэтому существует много способов, которыми эта проблема могла быть решена.
Существует одна реальная проблема, что преобразование int argc, ...
перешел в makecontext
в форму, передаваемую в функцию, нельзя сделать без серьезной помощи со стороны компилятора, если только соглашение о вызовах для функций с переменными и не переменными значениями не совпадает (и даже тогда весьма сомнительно, может ли это быть сделано надежно). Эта проблема, однако, могла быть решена просто путем отказа от использования makecontext
в любой форме, кроме makecontext(ucp, func, 1, (void *)arg);
,
Возможно, лучший вопрос, почему вы думаете ucontext.h
функции являются лучшим способом обработки потоков. Если вы хотите пойти с ними, я мог бы предложить написать интерфейс-обертку, который вы можете реализовать с помощью ucontext.h
или с pthreads, затем сравнивая производительность и раздувание. Это также будет иметь преимущество в том, что, если будущие системы откажутся от поддержки ucontext.h
, вы можете просто переключиться на компиляцию с реализацией на основе pthread, и все будет просто работать. (К тому времени, раздувание может быть менее важным, выгода от многоядерности /SMP, вероятно, будет огромной, и, надеюсь, реализации pthread будут менее раздутыми.)
Редактирование (на основе запроса OP): Для реализации "кооперативной потоковой обработки" с помощью pthreads вам нужны переменные условия. Вот достойное руководство по pthreads с информацией об их использовании:
https://computing.llnl.gov/tutorials/pthreads/
Ваш кооперативный многозадачный примитив "передача выполнения потоку X" будет выглядеть примерно так:
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);
Надеюсь, я все понял; по крайней мере, общая идея верна. Если кто-то видит ошибки, пожалуйста, прокомментируйте, чтобы я мог это исправить. Половина блокировки (other_thread
мьютекс), вероятно, совершенно не нужен для такого рода использования, так что вы могли бы сделать мьютекс локальной переменной в task_switch
функция. Все, что вы действительно будете делать, это использовать pthread_cond_wait
а также pthread_cond_signal
как "иди спать" и "проснись другой нитью" примитивы.
Для чего это стоит, есть Boost.Context
библиотека, которая была недавно принята и должна быть только включена в официальный релиз Boost. Boost.Context
адресован тем же сценариям использования, что и POSIX ucontext
семейство: низкое накладное кооперативное переключение контекста. Автор приложил много усилий с проблемами производительности.
Нет, для них нет стандартной замены.
Вы варианты
- продолжать использовать
<ucontext.h>
даже если они содержат устаревший C. - переключиться на pthreads
- написать свою собственную библиотеку
- использовать существующую (и, возможно, не очень переносимую) библиотеку параллельных потоков, такую как http://swtch.com/libtask/, хотя многие из таких библиотек реализованы поверх ucontext.h
Базовые спецификации открытых групп, выпуск 6, стандарт IEEE 1003.1, выпуск 2004 г.
Все еще перечисляет makecontext() и swapcontext() с тем же устаревшим синтаксисом. Я не видел ничего более недавнего.