技术控

    今日:72| 主题:49409
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] exec will eat your brain

[复制链接]
无需楚楚可怜 发表于 2016-10-5 14:04:33
142 0

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
This is about how fork and exec works on Unix. You might already know about this, but some people don't, and I was surprised when I learned it a few years back!
  So. You want to start a process. We've talked a lot about    system callson this blog -- every time you start a process, or open a file, that's a system call. So you might think that there's a system call like this  
     
  1. start_process(["ls", "-l", "my_cool_directory"])
复制代码
   This is a reasonable thing to think and apparently it's how it works in DOS/Windows. I was going to say that this    isn'thow it works on Linux. But! I went and looked at the docs and apparently there is a    posix_spawnsystem call that does basically this. Shows what I know. Anyway, we're not going to talk about that.  
  fork and exec

      posix_spawnon Linux is behind the scenes implemented in terms of 2 system calls called    forkand    exec(actually    execve), which are what people usually actually use anyway. On OS X apparently people use    posix_spawnand fork/exec are discouraged! But we'll talk about Linux.  
  Every process in Linux lives in a "process tree". You can see that tree by running    pstree. The root of the tree is    init, with PID 1. Every process (except init) has a parent, and any process has many children.  
  So, let's say I want to start a process called    lsto list a directory. Do I just have a baby    ls? No!  
  Instead of having children, what I do is you have a child that is a clone of myself, and then that child gets its brain eaten and turns into    ls. Really.  
  We start out like this:
     
  1. my parent
  2.     |- me
复制代码
   Then I run    fork(). I have a child which is a clone of myself.  
     
  1. my parent
  2.     |- me
  3.        |-- clone of me
复制代码
   Then I organize it so that my child runs    exec("ls"). That leaves us with  
     
  1. my parent
  2.     |- me
  3.        |-- ls
复制代码
   and once ls exits, I'll be all by myself again
     
  1. my parent
  2.     |- me
  3.        |-- ls
复制代码
   what fork and exec looks like in code

  This is one of the exercises you have to do if you're going to write a shell (which is a very fun and instructive project! Kamal has a great workshop on Github about how to do it:    https://github.com/kamalmarhubi/shell-workshop)  
  It turns out that with a bit of work & some C or Python skills you can write a very simple shell (like bash!) in C or Python in just a few hours (at least if you have someone sitting next to you who knows what they're doing, longer if not :)). I've done this and it was awesome.
  Anyway, here's what fork and exec look like in a program. I've written fake C pseudocode. Remember that    fork can fail!  
     
  1. int pid = fork();
  2. // now i am split in two! augh!
  3. // who am I? I could be either the child or the parent
  4. if (pid == 0) {
  5.     // ok I am the child process
  6.     // ls will eat my brain and I'll be a totally different process
  7.     exec(["ls"])
  8. } else if (pid == -1) {
  9.     // omg fork failed this is a disaster
  10. } else {
  11.     // ok i am the parent
  12.     // continue my business being a cool program
  13.     // I could wait for the child to finish if I want
  14. }
复制代码
   ok what does it mean for your brain to be eaten julia

  Processes have a lot of attributes!
  You have
  
       
  • open files (including open network connections)   
  • environment variables   
  • signal handlers (what happens when you run Ctrl+C on the program?)   
  • a bunch of memory (your "address space")   
  • registers   
  • an "executable" that you ran (/proc/$pid/exe)   
  • cgroups and namespaces ("linux container stuff")   
  • some other stuff that I'm forgetting  
  When you run    execveand have another program eat your brain, actually almost everything stays the same! You have the same environment variables and signal handlers and open files and more.  
  The only thing that changes is, well, all of your memory and registers and the program that you're running. Which is a pretty big deal.
  why is fork not super expensive (or: copy on write)

  You might ask "julia, what if I have a process that's using 2GB of memory! Does that mean every time I start a subprocess all that 2GB of memory gets copied?! That sounds expensive!"
  It turns out that Linux implements "copy on write" for fork() calls, so that for all the 2GB of memory in the new process it's just like "look at the old process! it's the same!". And then if the either process writes any memory, then at that point it'll start copying. But if the memory is the same in both processes, there's no need to copy!
  why you might care about all this

  Okay, julia, this is cool trivia, but why does it matter? Do the details about which signal handlers or environment variables get inherited or whatever actually make a difference in my day-to-day programming?
  Well, maybe! For example, there's this    delightful bug on Kamal's blog. It talks about how Python sets the signal handler for SIGPIPE to ignore. So if you run a program from inside Python, by default it will ignore SIGPIPE! This means that the program will    behave differentlydepending on whether you started it from a Python script or from your shell! And in this case it was causing a weird bug!  
  So, your program's environment (environment, signal handlers, etc.) can matter! It inherits its environment from its parent process, whatever that was! This can sometimes be a useful thing to know when debugging.
友荐云推荐




上一篇:Scala: Work With Files and Directories
下一篇:KoaHub.js可借助 Babel 编译稳定运行在 Node.js 环境上
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表