我们可以使用c在linux中创建进程的方法有多少

时间:2014-01-18 14:56:49

标签: c linux shell

我在Linux中创建进程时感到困惑。到目前为止,我认为我们可以通过调用以下系统调用来创建进程。

  1. system()
  2. exec()系列调用
  3. fork()系统调用
  4. 但:

    1. system():但是当“系统”系统调用执行shell和shell上的输入可执行文件时,正在创建一个子进程来执行输入。所以shell调用子进程然后我们可以说fork正在为此创建流程。

    2. exec系统调用:当这个系统调用时,用新进程写入当前正在运行的进程。所以它也创建了一个新进程但使用相同的地址空间。我认为它也在调用call fork来创建进程。

    3. 我很困惑以上所有这些都是创建新进程或只有fork系统的可行方法。

5 个答案:

答案 0 :(得分:11)

exec系列调用系统不会调用fork,也不会创建新进程。 它只用新的二进制文件覆盖现有的进程。

linux个用户程序中,fork是创建新流程的唯一功能。虽然fork内部调用了clone和其他系统调用

另一方面,system只是forkexec的包装。创建流程的实际任务由fork中的system完成。 因此system不是创建新流程的方法。

答案 1 :(得分:3)

fork()会创建您的流程副本。这是您在像Linux这样的POSIX环境中实际创建进程的地方。要准确回答您的问题标题,fork()是创建流程的唯一方法。

exec()为您做的是用另一个进程替换进程(例如您刚用fork()创建的进程),因此exec()本身不会创建进程但通常伴随着fork(),因为您通常希望创建另一个与当前流程不同的流程。

system()电话下方,只有fork()后跟exec(),因此这不是创建流程的新方法。

答案 2 :(得分:3)

在POSIX环境中,您可以通过fork系统调用创建进程,没有任何异常。 Fork将创建一个过程。

exec函数族只是将其他程序的二进制加载到当前进程的地址空间(调用exec()系统调用)。

system()中,内部使用fork()后跟exec()系统调用。

答案 3 :(得分:2)

创建新流程的方法只有两种:系统调用forkclone

提到的其他功能分为两类:

  1. exec() family:这些用其他程序替换进程的内容。通常在调用exec()fork后使用clone来将生成的流程之一转换为所需应用程序的流程。例如,当bash执行gcc命令时,它首先会自行分配,然后使用{{{} bash进程将gcc个进程中的一个转换为exec()进程1}}家庭。

  2. system()系列:它们封装了fork / clone系统调用和相应的exec()调用,可能会执行连接stdin之类的奇特内容和stdout

  3. 请注意,所有这些函数fork()clone()exec()system()等都是由标准C库定义的系统调用包装器(始终存在) ),而不是系统自称。因此,违反直觉,fork()是当前系统上clone系统调用的包装器。这并不重要。但是,C库函数是标准化的,系统调用不是。

    从历史上看,fork是旧的系统调用。虽然定义和使用其语义非常容易,但它总是受到其性能影响:整个过程环境需要(至少在逻辑上)被复制,但是,大部分工作都是无用的,作为最终的过程之一通常会被exec电话完全覆盖。此外,fork语义不允许创建线程。由于这些缺点,引入了clone调用,允许对复制的内容进行细粒度控制,以及在两个进程之间共享的内容,允许pthreads以{{1}的形式实现}。

答案 4 :(得分:2)

除了所有其他答案之外,并且要挑剔,过程由fork(2)(或过时的vfork(2) ...)和clone(2)系统调用创建(并且不, execve(2)系统调用不创建进程,但通过在同一进程中启动新程序来覆盖其地址空间和状态),但某些进程由内核“神奇地”创建,特别是:

  • /sbin/init由内核在启动时启动(如果找不到,则尝试其他一些程序,甚至/bin/sh ....);这是pid 1的过程很早就开始了......

  • 某些内核进程(或内核线程)由内核启动,如kswapdkworker(请参阅this问题)等等...我有超过50个内核流程或任务

  • Linux内核有时也会从内核域启动用户进程,特别是hotplug(8)modprobe等等。另请参阅udev等...

  • 几乎所有流程都由fork(或clone ...)启动,并且是/sbin/init的后代(或pid 1的流程)。 (但modprobehotplug可由内核启动,通常fork个其他进程。

创建流程(通过fork等......)非常有效。 shell正在分配几乎所有命令(除了内置命令,如cdulimit ...); clone是多线程所必需的(但可以用作fork的替代品...)

请注意,system(3)popen(3)库函数(不是system calls,它们列在syscalls(2) ...中)同时调用{ {1}}和fork(在execve上)daemon(3)是一个调用/bin/sh(两次)等的库函数...

使用strace(1)(找出程序正在执行的系统调用)并阅读Advanced Linux Programming

现在,最近的Libc正在使用fork以上clone(有些人不再调用fork系统调用,只有fork};你可以有几个libc,例如MUSL libc

GNU libc }