Linux上的clone()系统调用采用一个指向堆栈的参数,供新创建的线程使用。这样做的明显方法是简单地分配一些空间并传递该空间,但随后必须确保已分配了该线程将使用的尽可能多的堆栈空间(很难预测)。
我记得在使用pthreads时不必这样做,所以我很好奇它做了什么。我遇到了一个网站,该网站解释说:“
Linux
pthreads实现使用的最佳解决方案是使用mmap分配内存,并使用标志指定使用时分配的内存区域。这样,就可以为根据需要将其放入堆栈,如果系统无法分配额外的内存,则会发生分段冲突。”
我听说过mmap的唯一使用上下文是将文件映射到内存,并且确实要阅读mmap手册页,它需要一个文件描述符。如何将其用于分配动态长度堆栈以提供给clone()?该网站只是疯狂的吗?;)
在这两种情况下,内核是否都不需要知道如何为新堆栈查找空闲的内存束,因为在用户启动新进程时,它总是必须做的事情吗?如果内核已经可以弄清楚为什么还要首先指定堆栈指针呢?
约瑟夫,回答您的最后一个问题:
当用户创建“常规”新进程时,将由fork()完成。在这种情况下,内核根本不必担心创建新堆栈,因为新过程是旧堆栈的完全复制,一直到堆栈。
如果用户使用exec()替换当前正在运行的进程,则内核确实需要创建一个新的堆栈-
但是在这种情况下,这很容易,因为它是从空白开始的。exec()擦除进程的内存空间并重新初始化它,因此内核说“ exec()之后,堆栈始终在此处存在”。
但是,如果使用clone(),则可以说新进程将与旧进程(CLONE_VM)共享一个内存空间。在这种情况下,内核无法像在调用进程中那样离开堆栈(就像fork()一样),因为那样我们的两个进程将在彼此的堆栈上踩踏。内核也不能仅仅将其放在默认位置(就像exec()一样),因为该位置已经在此内存空间中占用了。唯一的解决方案是允许调用进程为其找到位置,这就是它的作用。
系统调用 我们要想启动一个进程,需要操作系统的调用(system call)。实际上操作系统和普通进程是运行在不同空间上的,操作系统进程运行在内核态(todo: kernel space),开发者运行的进程运行在用户态(todo: user space),这样有效规避了用户程序破坏系统的可能。 如果用户态进程想执行内核态的操作,只能通过系统调用了。Linux提供了超多系统调用函数,我们关注与进程相
编译器手册(dragon book)解释了值类型是在堆栈上创建的,引用类型是在堆上创建的。 对于Java,JVM在运行时数据区也包含堆和堆栈。对象和数组在堆上创建,方法框架被推到堆栈。一个堆由所有线程共享,而每个线程都有自己的堆栈。下图显示了这一点: 有关Java运行时数据区域的更多信息。 null
问题内容: 上X86-64英特尔系统,支持和什么是从64位用户代码“最快”的系统调用在香草内核? 特别是,它必须是一个执行/ user <->内核转换1的系统调用,但执行的工作量最少。它甚至不需要执行syscall本身:某种从不分派给内核侧特定调用的早期错误是可以的,只要它不会因此而走慢。 这样的调用可用于估计原始和开销,而与调用完成的任何工作无关。 1特别是,这不包括看似系统调用但在VDSO中实
本文向大家介绍Linux被中断的系统如何调用详解,包括了Linux被中断的系统如何调用详解的使用技巧和注意事项,需要的朋友参考一下 前言 慢系统调用,指的是可能永远无法返回,从而使进程永远阻塞的系统调用,比如无客户连接时的accept、无输入时的read都属于慢速系统调用。 在Linux中,当阻塞于某个慢系统调用的进程捕获一个信号,则该系统调用就会被中断,转而执行信号处理函数,这就是被中断的系统调
问题内容: Linux编程接口 在第3章中将进行如下练习: 当使用特定于Linux的reboot()系统调用来重新引导系统时,必须将第二个参数magic2指定为一组幻数(例如LINUX_REBOOT_MAGIC2)之一。这些数字的意义是什么?(将它们转换为十六进制提供了一个线索。) 手册页告诉我们可以是LINUX_REBOOT_MAGIC2(672274793),LINUX_REBOOT_MAGI
本文阐述Apache如何根据URL地址定位到文件在文件系统中的位置。 相关模块和指令 相关模块 相关指令 mod_alias mod_proxy mod_rewrite mod_userdir mod_speling mod_vhost_alias Alias AliasMatch CheckSpelling DocumentRoot ErrorDocument Options ProxyPass