首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程间的ucontext

线程间的ucontext
EN

Stack Overflow用户
提问于 2010-12-15 07:10:02
回答 2查看 2.3K关注 0票数 10

上下文(由ucontext.h中的函数操作的对象)允许跨线程共享吗?也就是说,我可以使用第二个参数在另一个线程上使用在makecontext中创建的上下文执行swapcontext吗?一个测试程序似乎表明这在Linux上是有效的。我找不到关于这方面的文档,而Windows fibers似乎明确支持这样的用例。这样做通常是安全的和可以的吗?这是标准的POSIX行为吗?

EN

回答 2

Stack Overflow用户

发布于 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的说法,可以在本机(内核)线程之间移动用户线程上下文:

代码语言:javascript
复制
        /*
         * 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):

代码语言:javascript
复制
/*
 * 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

代码语言:javascript
复制
    /* 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之间移植。

票数 6
EN

Stack Overflow用户

发布于 2011-07-08 15:42:49

man page

在类似System V的环境中,具有在中定义的类型ucontext_t和四个函数getcontext(2)、setcontext(2)、makecontext()和swapcontext(),它们允许在进程内的多个控制线程之间进行用户级上下文切换。

听起来这就是它的作用。

编辑:尽管this discussion似乎表明您不应该混合它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4445220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档