跨线程的 ucontext
上下文(由 ucontext.h
中的函数操作的对象)是否允许跨线程共享?也就是说,我可以使用第二个参数来 swapcontext
来作为另一个线程上的 makecontext
创建的上下文吗?测试程序似乎表明这可以在 Linux 上运行。我找不到这方面的文档,而 Windows 光纤似乎明确支持这种用例。一般来说,这样做安全吗?这是标准的 POSIX 行为吗?
Are contexts (the objects manipulated by functions in ucontext.h
) allowed to be shared across threads? That is, can I swapcontext
with the second argument being a context created in makecontext
on another thread? A test program seems to show this working on Linux. I can't find documentation one way or the other on this, whereas Windows fibers appear to explicitly support such a use case. Is this safe and OK to do in general? Is it standard POSIX behavior that this should work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
实际上,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 可以在本机(内核)线程之间移动用户线程上下文:
保存和恢复用户线程时,可以使用 ucontext ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_mctx.c:64 似乎这是一种首选方法 (
mcsc
):因此,即使 NGPT 已失效且未使用,它也会选择 *context() 来切换用户线程,甚至在内核线程之间切换。我认为,在 Linux 上使用 *context() 系列是足够安全的。
混合 ucontexts 和其他本机线程库时可能会出现一些问题。我会考虑 NPTL,它是自 glibc 2.4 以来的标准 Linux 本机线程库。主要问题是 THREAD_SELF - 指向当前线程的 struct pthread 的指针。 TLS(线程本地存储)也通过 THREAD_SELF 工作。 THREAD_SELF 通常存储在寄存器中(r2 on powerpc,
% x86 上的 gs
等)。 get/setcontext 可能会保存和恢复该寄存器,从而破坏本机 pthread 库的内部结构(例如线程本地存储、线程标识等)。glibc setcontext 不会保存/恢复
%gs
注册 以与 pthread 兼容:您应该检查 setcontext 是否在您感兴趣的架构上保存 THREAD_SELF 注册。此外,您的代码不能在操作系统和
libc
。Actually, there was an NGPT - threading library for linux, which uses not a current 1:1 threading model (each user thread is the kernel thread or LWP), but a M:N threading model (several user threads corresponds to another, smaller number of kernel threads).
According to ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_sched.c:170 pth_scheduler it was possible of moving user thread contexts between native (kernel) threads:
To save and restore user threads, the ucontext can be used ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_mctx.c:64 and seems this was a preferred method (
mcsc
):So, even if NGPT is dead and unused, it selected *context() for switching user threads even between kernel threads. I assume, that using *context() family is safe enough on Linux.
There can be some problems when mixing ucontexts and other native threads library. I will consider a NPTL, which is standard linux native threading library since glibc 2.4. The main problem is THREAD_SELF - pointer to
struct pthread
of the current thread. TLS (Thread-local storage) also works via THREAD_SELF. The THREAD_SELF is usually stored on register (r2 on powerpc,%gs
on x86, etc). get/setcontext might save and restore this register breaking internals of native pthread library (e.g. thread-local storage, thread identification, etc).The glibc setcontext will not save/restore
%gs
register to be compatible with pthreads:You should check, does setcontext saves THREAD_SELF register on the architecture you are interested in. Also, your code can be not portable between OSes and
libc
s.来自 手册页
听起来这就是它的用途。
编辑:尽管此讨论似乎表明您应该不要将它们混合在一起。
From the man page
Sounds like that's what it's for.
EDIT: although this discussion seems to indicate that you shouldn't be mixing them.