上下文(由ucontext.h中的函数操作的对象)允许跨线程共享吗?也就是说,我可以使用第二个参数在另一个线程上使用在makecontext中创建的上下文执行swapcontext吗?一个测试程序似乎表明这在Linux上是有效的。我找不到关于这方面的文档,而Windows fibers似乎明确支持这样的用例。这样做通常是安全的和可以的吗?这是标准的POSIX行为吗?
发布于 2011-07-08 15:58:04
实际上,linux有一个NGPT线程库,它使用的不是当前的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上使用*context()系列是足够安全的。
在混合ucontext和其他本机线程库时,可能会出现一些问题。我将考虑NPTL,它是从glibc 2.4开始的标准linux原生线程库。主要问题是指向当前线程的struct pthread的THREAD_SELF指针。TLS (线程本地存储)也通过THREAD_SELF工作。THREAD_SELF通常存储在寄存器中(r2 on powerpc、x86上的%gs等)。
与pthread兼容的glibc setcontext will not save/restore %gs register:
/* 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寄存器保存在您感兴趣的架构上。此外,您的代码不能在OSes和libc之间移植。
发布于 2011-07-08 15:42:49
从man page
在类似System V的环境中,具有在中定义的类型ucontext_t和四个函数getcontext(2)、setcontext(2)、makecontext()和swapcontext(),它们允许在进程内的多个控制线程之间进行用户级上下文切换。
听起来这就是它的作用。
编辑:尽管this discussion似乎表明您不应该混合它们。
https://stackoverflow.com/questions/4445220
复制相似问题