2010-12-14 10 views
10

Czy konteksty (obiekty manipulowane przez funkcje w ucontext.h) mogą być współużytkowane przez wątki? To znaczy, czy mogę swapcontext z drugim argumentem będącym kontekstem utworzonym w makecontext na innym wątku? Wygląda na to, że program testowy działa na systemie Linux. Nie mogę znaleźć dokumentacji w ten czy inny sposób, podczas gdy włókna Windows wydają się wyraźnie wspierać taki przypadek użycia. Czy to jest ogólnie bezpieczne i OK? Czy to standardowe zachowanie POSIX, że to powinno działać?ucontext w wątkach

+1

Czy możesz umieścić swój program testowy, tutaj? – vpit3833

Odpowiedz

0

Z man page

W V jak środowisko, po jednym ma ucontext_t typu określonego w i cztery funkcje getContext (2), setcontext (2) makecontext() i swapcontext(), że umożliwia przełączanie kontekstu na poziomie użytkownika pomiędzy wieloma wątkami kontrolki w ramach procesu.

Wygląda na to, do czego służy.

EDYCJA: chociaż this discussion wydaje się wskazywać, że nie powinieneś ich mieszać.

+2

Nie. To mówi o "wątkach kontroli", wątkach, które są zapisywane i przywracane przez * context(). Nie mówi nic o mieszaniu * funkcji context() i pthreadów. – osgx

+0

Czy dyskusja [Solaris] (http://groups.google.com/group/comp.programming.threads/browse_thread/thread/c29c8a84e16fdba9) jest przydatna? Dlaczego, na Boga, chcesz to zrobić? Gwintowanie jest wystarczająco śliskie, bez mieszania definicji nici. – spraff

+0

To nie dla mnie. Rodzime wątki mogą być wystarczające dla zwykłego C, ale niewystarczające dla 1) coroutines, np. in Go, itp. 2) języki z zielonymi wątkami, np. Ruby/Python – osgx

6

W rzeczywistości istniała biblioteka wątków NGPT dla linuxa, która używa nie bieżącego modelu gwintowania 1: 1 (każdy wątek użytkownika jest wątkiem jądra lub LWP), ale model wątkowania M: N (kilka wątków użytkownika odpowiada do innej, mniejszej liczby wątków jądra).

Według ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_sched.c:170 pth_scheduler można było poruszać konteksty wątku użytkownik między rodzimymi (jądro) wątków:

 /* 
     * 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; 

Aby zapisać i przywrócić wątki użytkownika, który to ucontext można stosować ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_mctx.c:64 i wydaje się, że był to korzystny sposób (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. 
*/ 

Tak więc, nawet jeśli NGPT jest martwy i nieużywane, to wybrany kontekst *() do przełączania wątków użytkownika nawet pomiędzy wątkami jądra. Zakładam, że używanie rodziny * context() jest wystarczająco bezpieczne w Linuksie.

Podczas mieszania tekstu ucontexts i innych rodzimych wątków mogą wystąpić pewne problemy. Rozważę NPTL, który jest standardową linuxową biblioteką wątków od glibc 2.4. Głównym problemem jest THREAD_SELF - wskaźnik do struct pthread bieżącego wątku. TLS (Thread-local storage) działa również przez THREAD_SELF. THREAD_SELF jest zwykle przechowywany w rejestrze (r2 on powerpc, %gs na x86 itd.). get/setcontext może zapisywać i przywracać ten rejestr łamiąc wewnętrzne elementy natywnej biblioteki pthread (np. pamięć lokalną wątku, identyfikację wątków itp.).

Glibc setcontext will not save/restore %gs register być zgodne z 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 

Należy sprawdzić, czy setcontext oszczędza THREAD_SELF zarejestrować na architekturze jesteś zainteresowany Ponadto, kod może nie być przenośny między systemami operacyjnymi i libc. s.

+0

Nie do końca satysfakcjonujący, ale myślę, że to najlepsze informacje, jakie możesz mieć. Dzięki. – Flavio

Powiązane problemy