2010-12-14 10 views
10

I contesti (gli oggetti manipolati dalle funzioni in ucontext.h) possono essere condivisi tra thread? Cioè, posso swapcontext con il secondo argomento di un contesto creato in makecontext su un altro thread? Un programma di test sembra mostrare che funziona su Linux. Non riesco a trovare la documentazione in un modo o nell'altro, mentre le fibre di Windows sembrano supportare esplicitamente tale caso d'uso. Questo è sicuro e OK da fare in generale? Il comportamento POSIX standard dovrebbe funzionare?ucontext attraverso i thread

+1

Puoi pubblicare anche il tuo programma di test, qui? – vpit3833

risposta

0

Dal man page

In un ambiente di sistema V-like, uno ha il tipo ucontext_t definito nella e quattro funzioni getContext (2), setContext (2), makecontext() e swapcontext() che consente il cambio di contesto a livello utente tra più thread del controllo all'interno di un processo.

Suona come questo è quello che è per.

MODIFICA: sebbene this discussion sembra indicare che non si devono mescolare.

+2

No. Si tratta di "thread di controllo", i thread che vengono salvati e ripristinati da * context(). Non dice nulla sulla combinazione di funzioni * context() e pthreads. – osgx

+0

La discussione [Solaris] (http://groups.google.com/group/comp.programming.threads/browse_thread/thread/c29c8a84e16fdba9) è utile? Perché mai vuoi farlo comunque? La filettatura è abbastanza scivolosa così com'è senza mescolare le definizioni dei thread. – spraff

+0

Non fa per me. I fili nativi possono essere sufficienti per la C normale, ma non per 1) coroutine, ad es. in Go, ecc. 2) lingue con thread verdi, ad es. Ruby/Python – osgx

6

In realtà, esisteva una libreria di threading NGPT per linux, che non utilizza un modello di threading corrente 1: 1 (ogni thread utente è il thread del kernel o LWP), ma un modello di threading M: N corrisponde a diversi thread utente ad un altro, un numero minore di thread del kernel).

Secondo ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_sched.c:170 pth_scheduler era possibile spostare i contesti filetto utente tra nativi (kernel) discussioni:

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

Per salvare e ripristinare thread utente, l'ucontext può essere utilizzato ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_mctx.c:64 e sembra questo era un metodo preferito (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. 
*/ 

Quindi, anche se NGPT è morto e inutilizzato, ha selezionato * contesto() per la commutazione thread utente anche tra thread del kernel. Presumo che usare la famiglia * context() sia abbastanza sicuro su Linux.

Ci possono essere alcuni problemi durante il mixaggio di ucontexts e altra libreria di thread nativi. Prenderò in considerazione un NPTL, che è una libreria di threading nativa Linux standard poiché glibc 2.4. Il problema principale è THREAD_SELF - puntatore a struct pthread del thread corrente. TLS (Thread-local storage) funziona anche tramite THREAD_SELF. Il THREAD_SELF viene solitamente memorizzato nel registro (r2 on powerpc, %gs su x86, ecc.). get/setcontext potrebbe salvare e ripristinare questo interno di rottura del registro della libreria pthread nativa (ad es. archiviazione locale del thread, identificazione del thread, ecc.).

La glibc setContext will not save/restore %gs register per essere compatibile con 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 

Si dovrebbe controllare, vuol setContext salva THREAD_SELF registrarsi sulla architettura che ti interessa Inoltre, il codice può essere non portabile tra sistemi operativi e libc. S.

+0

Non del tutto soddisfacente, ma suppongo che siano le migliori informazioni che puoi avere in giro. Grazie. – Flavio

Problemi correlati