Переключение контекста - ucontext_t и makecontext()

Я изучаю переключение контекста в программировании на C и нашел следующий пример кода в Интернете. Я пытаюсь выяснить, только ли makecontext() Функция может вызвать функцию, которая что-то делает. Другие функции, такие как setcontext(), getcontext(), а также swapcontext() используются для установки контекста.

makecontext() присоединяет функцию и ее параметр (ы) к контексту, прилипает ли функция к контексту все время, пока к ней не будет внесено изменение?

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <ucontext.h>
  4 #define MEM 64000
  5 
  6 ucontext_t T1, T2, Main;
  7 ucontext_t a;
  8 
  9 int fn1()
 10 {
 11   printf("this is from 1\n");
 12   setcontext(&Main);
 13 }
 14 
 15 void fn2()
 16 {
 17   printf("this is from 2\n");
 18   setcontext(&a);
 19   printf("finished 1\n");
 20 }
 21 
 22 void start()
 23 {
 24   getcontext(&a);
 25   a.uc_link=0;
 26   a.uc_stack.ss_sp=malloc(MEM);
 27   a.uc_stack.ss_size=MEM;
 28   a.uc_stack.ss_flags=0;
 29   makecontext(&a, (void*)&fn1, 0);
 30 }
 31 
 32 int main(int argc, char *argv[])
 33 {
 34   start();
 35   getcontext(&Main);
 36   getcontext(&T1);
 37   T1.uc_link=0;
 38   T1.uc_stack.ss_sp=malloc(MEM);
 39   T1.uc_stack.ss_size=MEM;
 40   makecontext(&T1, (void*)&fn1, 0);
 41   swapcontext(&Main, &T1);
 42   getcontext(&T2);
 43   T2.uc_link=0;
 44   T2.uc_stack.ss_sp=malloc(MEM);
 45   T2.uc_stack.ss_size=MEM;
 46   T2.uc_stack.ss_flags=0;
 47   makecontext(&T2, (void*)&fn2, 0);
 48   swapcontext(&Main, &T2);
 49   printf("completed\n");
 50   exit(0);
 51 }

1 ответ

Решение

makecontext записывает информацию о функции в контекст, и она остается там до тех пор, пока не будет перезаписана чем-то другим. getcontext перезаписывает весь контекст, поэтому будет перезаписывать любую функцию, написанную там предыдущим вызовом makecontext, Точно так же, swapcontext полностью перезаписывает контекст, на который указывает его первый аргумент.

Основная идея заключается в том, что u_context содержит снимок части контекста процесса в определенный момент времени. Он содержит все машинные регистры, информацию о стеке и маски сигналов. Он НЕ включает карту памяти или состояние дескриптора файла. Государство в u_context это именно то состояние, которое вам нужно манипулировать для реализации потоков или сопрограмм.

редактировать

swapcontext(&current, &another) сохраняет текущий контекст в current и переключается на another, В какой-то более поздний момент код another контекст) может переключиться обратно на current (с другим вызовом swapcontext) или это может переключиться на какой-то третий контекст. Когда контекст заканчивается (функция устанавливается в него с помощью makecontext возвращается), если на какой-то контекст указывает его uc_link поле, он переключится на этот контекст. Но если uc_link NULL, то поток (и процесс, если есть только один поток) выйдет - другие контексты, которые не работают, будут просто прекращены.

Другие вопросы по тегам