2010-12-14 3 views
10

Являются ли контексты (объекты, управляемые функциями в ucontext.h) разрешенными для общего доступа? То есть, может ли я swapcontext со вторым аргументом, являющимся контекстом, созданным в makecontext в другом потоке? Кажется, что тестовая программа показывает эту работу в Linux. Я не могу найти документацию так или иначе, в то время как волокна Windows явно поддерживают такой вариант использования. Это безопасно и нормально делать вообще? Является ли это стандартным поведением POSIX, что это должно работать?ucontext через потоки

+1

Можете ли вы опубликовать свою тестовую программу, здесь? – vpit3833

ответ

0

От man page

в V-среде System, один имеет тип ucontext_t, определенный в и четыре функции getcontext (2), SetContext (2), makecontext() и swapcontext(), который разрешает переключение контекста на уровне пользователя между несколькими потоками управления в рамках процесса.

Звучит так, как будто это для.

EDIT: хотя this discussion, кажется, указывает, что вы не должны смешивать их.

+2

№ Это говорит о «потоках управления», потоках, которые сохраняются и восстанавливаются с помощью * context(). В нем ничего не говорится о смешении функций * context() и pthreads. – osgx

+0

Является ли обсуждение [Solaris] (http://groups.google.com/group/comp.programming.threads/browse_thread/thread/c29c8a84e16fdba9) полезным? Почему же вы все равно хотите это сделать? Нарезание резьбы достаточно скользко, так как оно не смешивает определения резьбы. – spraff

+0

Его не для меня. Нативные потоки могут быть достаточно равны C, но недостаточно для 1) сопрограмм, например. в Go и т. д. 2) языки с зелеными нитями, например. Ruby/Python – osgx

6

На самом деле, была создана библиотека потоковой передачи NGPT для linux, которая использует не текущую модель потоков 1: 1 (каждый пользовательский поток является потоком ядра или LWP), но модель потоков M: N (несколько пользовательских потоков соответствуют к другому, меньшее количество потоков ядра).

По ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_sched.c:170 pth_scheduler можно было перемещать пользователь нить контексты между носителями (ядра) нитями:

 /* 
     * See if the thread is unbound... 
     * Break out and schedule if so... 
     */ 
     if (current->boundnative == 0) 
      break; 
     /* 
     * See if the thread is bound to a different native thread... 
     * Break out and schedule if not... 
     */ 
     if (current->boundnative == this_sched->lastrannative) 
      break; 

Для сохранения и восстановления пользовательских потоков, то ucontext может быть использован ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_mctx.c:64 и кажется, что это был предпочтительный метод (mcsc):

/* 
* save the current machine context 
*/ 
#if PTH_MCTX_MTH(mcsc) 
#define pth_mctx_save(mctx) \ 
     ((mctx)->error = errno, \ 
      getcontext(&(mctx)->uc)) 
#elif 
.... 
/* 
* restore the current machine context 
* (at the location of the old context) 
*/ 
#if PTH_MCTX_MTH(mcsc) 
#define pth_mctx_restore(mctx) \ 
     (errno = (mctx)->error, \ 
      (void)setcontext(&(mctx)->uc)) 
#elif PTH_MCTX_MTH(sjlj) 
... 

#if PTH_MCTX_MTH(mcsc) 

/* 
* VARIANT 1: THE STANDARDIZED SVR4/SUSv2 APPROACH 
* 
* This is the preferred variant, because it uses the standardized 
* SVR4/SUSv2 makecontext(2) and friends which is a facility intended 
* for user-space context switching. The thread creation therefore is 
* straight-foreward. 
*/ 

Таким образом, даже если NGPT мертв и не используется, он выбран * контекст() для переключения пользовательских потоков даже между потоками ядра. Я предполагаю, что использование семейства * context() достаточно безопасно для Linux.

При смешивании ucontexts и другой собственной библиотеки потоков могут возникать проблемы. Я рассмотрю NPTL, который является стандартной библиотекой потоковых потоков linux с glibc 2.4. Основной проблемой является THREAD_SELF - указатель на struct pthread текущего потока. TLS (локальное хранилище потоков) также работает через THREAD_SELF. THREAD_SELF обычно хранится в регистре (r2 on powerpc, %gs на x86 и т. Д.). get/setcontext может сохранять и восстанавливать этот регистр, нарушающий внутренности собственной библиотеки pthread (например, локальное хранилище потоков, идентификация потоков и т. д.).

Glibc SetContext will not save/restore %gs register быть совместим с Pthreads:

/* Restore the FS segment register. We don't touch the GS register 
     since it is used for threads. */ 
    movl oFS(%eax), %ecx 
    movw %cx, %fs 

Вы должны проверить, действительно SetContext сохраняет THREAD_SELF регистра на архитектуре вы заинтересованы Кроме того, ваш код может быть не переносим между операционными системами и libc. s.

+0

Не совсем удовлетворительно, но я думаю, это лучшая информация, которую вы можете иметь. Благодарю. – Flavio

Смежные вопросы