进程创建

Posted zuofaqi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程创建相关的知识,希望对你有一定的参考价值。

在linux下,创建进程可以使用两个glibc函数,分别是 fork, vfork

fork

fork函数用来创建一个子进程,声明如下:

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

fork函数,一次调用,两次返回。在父进程,返回值是子进程的进程ID,在子进程,返回的是0, 可以使用getppid函数获取父进程的进程号。

fork内部调用clone系统调用。创建的子进程虽然和父进程运行在不同的内存空间,但是子进程完全复制父进程的代码和数据,刚创建成功时,两个内存空间的内容是完全一样的。这个复制使用的是写时复制。

两个进程也有很多不同:

  • 进程号
  • 内存锁
  • 子进程的进程资源和CPU使用时间重置为0
  • 子进程等待信号为空
  • 子进程不继承定时器、IO操作

如果fork返回-1,表示创建进程失败,errno 被设置

fork失败的原因有:

  • 系统创建的进程达到最大进程数目限制。这时候,最好检查一下僵尸进程
  • 系统内存使用完了

 

子进程完全复制父进程代码

#include <sys/types.h>
#include <sys/unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>


int main()
{
    pid_t id = -1;

    for (int i = 0; i < 2; i++)
    {
        id = fork();
        if (id > 0)
        {
            printf("parent pid: %d
", getpid());
        }
        else if (id == 0)
        {
            printf("child pid: %d
", getpid());
        }
        else
        {
            perror("fork");
        }
    }

    return 0;
}

这段代码执行结果是:

parent pid: 18992
parent pid: 18992
child pid: 18993
child pid: 18994
parent pid: 18993
child pid: 18995

我们看到,for循环执行了两次,但是产生了4个不同的进程。循环n次,就创建 2^n 个进程

父子进程的执行顺序是不确定的

如果想让两个进程保持顺序,需要用到同步的方法了

 vfork

和fork比较,

vfork不会复制父进程的数据段,它适合在子进程直接调用exec族函数。在子进程调用exec,exit之前,父子进程共享数据段

父进程会阻塞,直到子进程调用exec或者退出

#include <sys/types.h>
#include <sys/unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>


int main()
{
    pid_t id = -1;

    id = vfork();
    if (id > 0)
    {
        printf("parent process...
");
    }
    else if (id == 0)
    {
        sleep(1);
        execl("/bin/ls", "ls", nullptr);
    }

    return 0;
}

 


以上是关于进程创建的主要内容,如果未能解决你的问题,请参考以下文章

代码片段:Shell脚本实现重复执行和多进程

LINUX PID 1和SYSTEMD PID 0 是内核的一部分,主要用于内进换页,内核初始化的最后一步就是启动 init 进程。这个进程是系统的第一个进程,PID 为 1,又叫超级进程(代码片段

Android 逆向Android 进程注入工具开发 ( Visual Studio 开发 Android NDK 应用 | Visual Studio 中 SDK 和 NDK 安装位置 )(代码片段

创建自己的代码片段(CodeSnippet)

线程学习知识点总结

多个请求是多线程吗