где есть пример переключения контекста - PullRequest
0 голосов
/ 29 апреля 2011

предполагается, что указатель функции, указывающий на A, передается в pthread_create, и после запуска потока я изменяю адрес указателя функции на статическую функцию B с A

.и B с push и pop, как я хотел бы сохранить контекст функции A при прерывании потока

любой пример, чтобы показать это переключение контекста

1 Ответ

0 голосов
/ 29 апреля 2011

Сложно сказать, о чем ты здесь спрашиваешь ... но я попробую.

Что касается вашего первого абзаца, я думаю, что вы спрашиваете, что произойдет, когда вы передадите указатель функции (который указывает на функцию A()) на pthread_create(), а затем измените указатель функции, чтобы он указывал на другой функция (функция B()). Ответ заключается в том, что изменение указателя функции не влияет на работающий поток; поскольку вы передали копию указателя функции на pthread_create(), работающий поток не обнаружит, что вы измените указатель на функцию позже.

Я полагаю, что вы действительно ищете что-то еще: как реализован переключатель контекста потока? Предположим на данный момент, что вы выполняете совместную многозадачность, т. Е. Работающий поток явно должен выдавать ЦП, вызывая функцию yield(). Вот псевдокод того, как может выглядеть простая функция yield; мы будем называть текущий поток «поток А», а поток, на который мы переключаемся, «поток В»:

void yield()
{
    Save all registers to the stack
    Save current stack pointer in some data structure dedicated to thread A
    Choose a different thread to yield to (in our case, this is thread B)
    Change stack pointer to the stack pointer that was saved for thread B
    Restore registers
}

Это верно, переключение контекста потока, по сути, просто означает переключение указателя стека на другой стек. Ключевым эффектом этого является то, что адрес возврата в стеке больше не тот, который был помещен в стек, когда поток A вызвал yield(); вместо этого адрес возврата является тем, который поток B поместил в стек в последний раз, когда он называется yield(). Таким образом, когда yield() возвращается, он возвращается туда, где поток B был в последний раз, когда передавал управление процессору.

Довольно забавно, а? Требуется минута, чтобы обернуть вокруг нее голову.

Если вы хотите расширить эту совместную многозадачность до вытесняющей многозадачности, то все, что вам нужно сделать в принципе, - это создать прерывание, которое будет вызываться через равные промежутки времени таймером; процедура обработки прерывания для этого прерывания просто yield().

Реальные реализации должны иметь гораздо больше деталей, но в принципе это все, что нужно для потокового переключения контекста - это просто означает переключение стеков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...