谁创建并拥有调用堆栈,并且调用堆栈如何在多线程中工作?

问题描述 投票:0回答:2

我知道每个线程通常只有一个调用堆栈,这只是一块内存,并通过使用esp和ebp进行控制。

1,如何创建这些调用堆栈,以及由谁负责?我的猜测是运行时,例如iOS应用程序的Swift运行时。线程是通过esp和ebp还是通过运行时直接与其自己的调用堆栈通信?

2,对于每个调用堆栈,它们必须使用esp和ebb cpu寄存器,如果我有一个2核4线程的CPU,那么说它具有4核(指令集)。这是否意味着每个调用堆栈只能在特定内核中使用这些寄存器?

ios swift multithreading assembly runtime
2个回答
2
投票

((我假设Swift线程就像其他语言的线程一样。确实没有很多好的选择,或者是普通的OS级别的线程,或者是用户空间的“绿色线程”,或者是两者的混合。仅在发生上下文切换的地方;主要概念仍然相同)


每个线程都有自己的堆栈,由mmap或父线程(或由创建该线程的同一系统调用)在进程的地址空间中分配。 IDK iOS系统调用。在Linux中,您必须将void *child_stack传递给实际上创建新线程的Linux-specific clone(2)系统调用。直接使用低级特定于操作系统的系统调用非常罕见;语言运行时可能会在诸如clone(2)之类的pthread函数之上执行线程处理,并且该pthreads库将处理特定于OS的详细信息。


[是的,每个软件线程都有其自己的体系结构状态,包括x86-64上的RSP或pthread_create。 (如果制作过时的32位x86代码,则使用ESP)。我认为帧指针对于swift是可选的。

是,每个逻辑核心都有其自己的架构状态(包括堆栈指针的寄存器);软件线程在逻辑核心上运行,并且在软件线程之间进行上下文切换以保存/恢复寄存器。相关,可能是sp on AArch64的副本。

软件线程共享相同的页表(虚拟地址空间),但not寄存器。


0
投票

XNU内核完成了。 Swift线程是POSIX pthread。在程序启动期间,XNU内核处理Mach-O可执行格式,并处理现代sp或旧版What resources are shared between threads?加载命令。这在内核函数中处理:

LC_MAIN

LC_UNIXTHREAD

恰好是static load_return_t load_main( struct entry_point_command *epc, thread_t thread, int64_t slide, load_result_t *result )

[static load_return_t load_unixthread( struct thread_command *tcp, thread_t thread, int64_t slide, load_result_t *result ) 通过open source初始化堆栈

[LC_MAINthread_userstackdefault

我尚未研究主线程以外的其他线程的堆栈创建内部细节。

我确实相信您对Swift运行时责任的怀疑可能是由于经常在堆栈上存储数据结构(例如LC_UNIXTHREAD-无双关语)(这是实施细节,不能保证运行时的功能)。关键是这个特定的堆栈与线程堆栈有本质上的不同,并且此process Swift运行时堆栈在所有线程之间共享。

© www.soinside.com 2019 - 2024. All rights reserved.