Linux:进程的本质和fork初识

news2024/11/24 22:33:02

文章目录

  • 回顾进程
  • 查看进程的方式
  • fork

回顾进程

前面对进程进行了一些初步的认知,比如进程=可执行程序+内核数据结构PCB,再比如可以通过ps命令搭配管道寻找进程,通过/proc系统文件夹查看进程的信息,这些都是前面对进程建立起来的一些初步的认知

查看进程的方式

下面引入在函数中使用进程的函数,getpid()gitppid

#include <stdio.h>
#include <unistd.h>

int main()
{
    while(1)
    {
        printf("process id:%d,parent process id:%d\n",getpid(),getppid());
        sleep(1);
    }
    return 0;
}

这两个函数的功能,就是得到进程的id和父进程的id

实现Makefile

cc=gcc
src=process.c
target=process 

$(target):$(src)
	gcc -o $@ $^
.PHONY:clean
clean:
	rm -f $(target)

在启动程序前,为了便于观察进程的变化情况,我们可以借助ps命令来观察,但是ps命令不能做到实时观察目前我们的进程变换情况,因此使用一个脚本来自动的观察进程的情况

# 打印ps指令的题头和利用ps指令寻找关于process的进程信息,打印一次暂停1s,再使用####进行分割每次打印的信息
while :; do ps ajx |head -1 && ps ajx | grep process; sleep 1;echo "###################################"; done

执行程序和脚本

在这里插入图片描述
下面对这个程序进行多次执行

# 第一次可执行程序运行的结果
process id:11389,parent process id:7945

# 进程监视的结果
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 7945 11389 11389  7945 pts/0    11389 S+    1003   0:00 ./process
# 第二次可执行程序运行的结果
process id:14823,parent process id:7945

# 进程监视的结果
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 7945 14823 14823  7945 pts/0    14823 S+    1003   0:00 ./process
# 第三次可执行程序运行的结果
process id:15279,parent process id:7945

# 进程监视的结果
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 7945 15279 15279  7945 pts/0    15279 S+    1003   0:00 ./process

输出结果如上,从中可以看出这个函数是可以打印出进程的信息的,和实际的信息也确实对应,但是有一个现象,父进程一直都是7945,为什么不变呢?

理解系统接口调用

从这里其实可以更深层次的理解下图中关于系统调用接口的概念,我们使用的不管是getpid还是getppid,实际上都是要调用系统的接口,操作系统再帮我们进行一个搜索后把结果返还给用户,逻辑上是很简单的一个过程
在这里插入图片描述
那么现在有了函数的调用,用户也可以直接去得到进程的id信息,下面进行第二种查看进程的方式,使用/proc文件来查看

proc文件夹,是一个动态的目录结构,里面存放的是所有存在的进程,而目录的名称就是以这个进程的id来命名的

下面展示了/proc文件夹下的各种进程内容,每一个文件夹其实都对应了一个进程,每一个进程文件夹下的内容其实就是每个进程的PCB,那么下面就要进入进程内,看这些进程内到底包含什么东西

[test@VM-16-11-centos process]$ ls /proc -l
total 0
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 1
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 10
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 1005
dr-xr-xr-x  9 test           test                         0 Sep 23 19:42 10082
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 106
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 1070
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 1072
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 1075
dr-xr-xr-x  9 root           root                         0 Sep 23 19:45 10935
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 11
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 1180
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 1188
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 1195
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 12
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 1205
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 1206
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 13
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 1318
dr-xr-xr-x  9 postfix        postfix                      0 Jul 15 22:07 1328
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 1370
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 14
dr-xr-xr-x  9 postfix        postfix                      0 Sep 23 19:55 14576
dr-xr-xr-x  9 root           root                         0 Sep 11 17:53 14808
dr-xr-xr-x  9 root           root                         0 Sep 11 17:53 14911
dr-xr-xr-x  9 root           root                         0 Aug 30 10:08 15264
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 1565
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 16
dr-xr-xr-x  9 root           root                         0 Sep 23 20:03 17216
dr-xr-xr-x  9 root           root                         0 Sep 23 20:05 17758
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 18
dr-xr-xr-x  9 ntp            ntp                          0 Jul 15 22:07 1800
dr-xr-xr-x  9 test           test                         0 Sep 23 20:09 18814
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 19
dr-xr-xr-x  9 root           root                         0 Sep 23 20:10 19001
dr-xr-xr-x  9 root           root                         0 Sep 23 20:12 19441
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 2
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 20
dr-xr-xr-x  9 root           root                         0 Aug 31 20:02 20043
dr-xr-xr-x  9 root           root                         0 Aug 31 20:02 20051
dr-xr-xr-x  9 root           root                         0 Aug 31 20:02 20052
dr-xr-xr-x  9 root           root                         0 Sep 23 20:15 20184
dr-xr-xr-x  9 test           test                         0 Sep 23 20:15 20221
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 203
dr-xr-xr-x  9 test           test                         0 Sep 12 12:11 20530
dr-xr-xr-x  9 test           test                         0 Sep 12 12:11 20543
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 21
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 22
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 23
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 24
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 25
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 253
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 26
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 262
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 267
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 268
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 269
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 27
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 272
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 277
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 28
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 29
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 292
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 293
dr-xr-xr-x  9 root           root                         0 Sep 22 18:22 29767
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 300
dr-xr-xr-x  9 root           root                         0 Sep 23 19:15 3061
dr-xr-xr-x  9 root           root                         0 Sep 21 20:36 3243
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 35
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 36
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 37
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 38
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 381
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 4
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 404
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 409
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 46
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 48
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 49
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 501
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 51
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 515
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 52
dr-xr-xr-x  9 root           root                         0 Jul 15 22:16 5449
dr-xr-xr-x  9 libstoragemgmt libstoragemgmt               0 Jul 15 22:07 556
dr-xr-xr-x  9 dbus           dbus                         0 Jul 15 22:07 561
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 566
dr-xr-xr-x  9 root           root                         0 Jul 15 22:07 567
dr-xr-xr-x  9 polkitd        polkitd                      0 Jul 15 22:07 568
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 6
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 612
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 613
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 614
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 615
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 616
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 621
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 65
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 7
dr-xr-xr-x  9 root           root                         0 Sep 23 19:34 7937
dr-xr-xr-x  9 test           test                         0 Sep 23 19:34 7944
dr-xr-xr-x  9 test           test                         0 Sep 23 19:34 7945
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 8
dr-xr-xr-x  9 root           root                         0 Sep 11 17:49 9
dr-xr-xr-x  2 root           root                         0 Sep 23 20:15 acpi
-r--r--r--  1 root           root                         0 Sep 23 20:15 buddyinfo
dr-xr-xr-x  4 root           root                         0 Sep 23 20:15 bus
-r--r--r--  1 root           root                         0 Sep 23 20:15 cgroups
-r--r--r--  1 root           root                         0 Sep 23 20:15 cmdline
-r--r--r--  1 root           root                         0 Sep 23 20:15 consoles
-r--r--r--  1 root           root                         0 Sep 23 20:15 cpuinfo
-r--r--r--  1 root           root                         0 Sep 23 20:15 crypto
-r--r--r--  1 root           root                         0 Sep 23 20:15 devices
-r--r--r--  1 root           root                         0 Sep 23 20:15 diskstats
-r--r--r--  1 root           root                         0 Sep 23 20:15 dma
dr-xr-xr-x  3 root           root                         0 Sep 23 20:15 driver
-r--r--r--  1 root           root                         0 Sep 23 20:15 execdomains
-r--r--r--  1 root           root                         0 Sep 23 20:15 fb
-r--r--r--  1 root           root                         0 Sep 23 20:15 filesystems
dr-xr-xr-x  5 root           root                         0 Sep 23 20:15 fs
-r--r--r--  1 root           root                         0 Sep 23 20:15 interrupts
-r--r--r--  1 root           root                         0 Sep 23 20:15 iomem
-r--r--r--  1 root           root                         0 Sep 23 20:15 ioports
dr-xr-xr-x 25 root           root                         0 Sep 23 20:15 irq
-r--r--r--  1 root           root                         0 Sep 23 20:15 kallsyms
-r--------  1 root           root           140737486266368 Sep 23 20:15 kcore
-r--r--r--  1 root           root                         0 Sep 23 20:15 keys
-r--r--r--  1 root           root                         0 Sep 23 20:15 key-users
-r--------  1 root           root                         0 Sep 23 20:15 kmsg
-r--------  1 root           root                         0 Sep 23 20:15 kpagecount
-r--------  1 root           root                         0 Sep 23 20:15 kpageflags
-r--r--r--  1 root           root                         0 Sep 23 20:15 loadavg
-r--r--r--  1 root           root                         0 Sep 23 20:15 locks
-r--r--r--  1 root           root                         0 Sep 23 20:15 mdstat
-r--r--r--  1 root           root                         0 Sep 23 20:15 meminfo
-r--r--r--  1 root           root                         0 Sep 23 20:15 misc
-r--r--r--  1 root           root                         0 Sep 23 20:15 modules
lrwxrwxrwx  1 root           root                        11 Sep 23 20:15 mounts -> self/mounts
-rw-r--r--  1 root           root                         0 Sep 23 20:15 mtrr
lrwxrwxrwx  1 root           root                         8 Sep 23 20:15 net -> self/net
-r--------  1 root           root                         0 Sep 23 20:15 pagetypeinfo
-r--r--r--  1 root           root                         0 Sep 23 20:15 partitions
-r--r--r--  1 root           root                         0 Sep 23 20:15 sched_debug
-r--r--r--  1 root           root                         0 Sep 23 20:15 schedstat
dr-xr-xr-x  3 root           root                         0 Sep 23 20:15 scsi
lrwxrwxrwx  1 root           root                         0 Jul 15 22:07 self -> 20221
-r--------  1 root           root                         0 Sep 23 20:15 slabinfo
-r--r--r--  1 root           root                         0 Sep 23 20:15 softirqs
-r--r--r--  1 root           root                         0 Sep 23 20:15 stat
-r--r--r--  1 root           root                         0 Jul 15 22:07 swaps
dr-xr-xr-x  1 root           root                         0 Jul 15 22:07 sys
--w-------  1 root           root                         0 Sep 23 20:15 sysrq-trigger
dr-xr-xr-x  2 root           root                         0 Sep 23 20:15 sysvipc
-r--r--r--  1 root           root                         0 Sep 23 20:15 timer_list
-rw-r--r--  1 root           root                         0 Sep 23 20:15 timer_stats
dr-xr-xr-x  4 root           root                         0 Sep 23 20:15 tty
-r--r--r--  1 root           root                         0 Sep 23 20:15 uptime
-r--r--r--  1 root           root                         0 Sep 23 20:15 version
-r--------  1 root           root                         0 Sep 23 20:15 vmallocinfo
-r--r--r--  1 root           root                         0 Sep 23 20:15 vmstat
dr-xr-xr-x  2 root           root                         0 Sep 23 20:15 xpmem
-r--r--r--  1 root           root                         0 Sep 23 20:15 zoneinfo

对于产生的结果过多,不太好观察,因此这里将前面的程序启动,看进程中到底有什么文件和信息可以进行获取

# 启动程序
process id:18814,parent process id:7945

# 查看进程内容
[test@VM-16-11-centos process]$ ls /proc/18814 -l
total 0
dr-xr-xr-x 2 test test 0 Sep 23 20:10 attr
-rw-r--r-- 1 test test 0 Sep 23 20:10 autogroup
-r-------- 1 test test 0 Sep 23 20:10 auxv
-r--r--r-- 1 test test 0 Sep 23 20:10 cgroup
--w------- 1 test test 0 Sep 23 20:10 clear_refs
-r--r--r-- 1 test test 0 Sep 23 20:09 cmdline
-rw-r--r-- 1 test test 0 Sep 23 20:10 comm
-rw-r--r-- 1 test test 0 Sep 23 20:10 coredump_filter
-r--r--r-- 1 test test 0 Sep 23 20:10 cpuset
lrwxrwxrwx 1 test test 0 Sep 23 20:09 cwd -> /home/test/process
-r-------- 1 test test 0 Sep 23 20:09 environ
lrwxrwxrwx 1 test test 0 Sep 23 20:09 exe -> /home/test/process/process
dr-x------ 2 test test 0 Sep 23 20:09 fd
dr-x------ 2 test test 0 Sep 23 20:10 fdinfo
-rw-r--r-- 1 test test 0 Sep 23 20:10 gid_map
-r-------- 1 test test 0 Sep 23 20:10 io
-r--r--r-- 1 test test 0 Sep 23 20:10 limits
-rw-r--r-- 1 test test 0 Sep 23 20:10 loginuid
dr-x------ 2 test test 0 Sep 23 20:10 map_files
-r--r--r-- 1 test test 0 Sep 23 20:10 maps
-rw------- 1 test test 0 Sep 23 20:10 mem
-r--r--r-- 1 test test 0 Sep 23 20:10 mountinfo
-r--r--r-- 1 test test 0 Sep 23 20:10 mounts
-r-------- 1 test test 0 Sep 23 20:10 mountstats
dr-xr-xr-x 5 test test 0 Sep 23 20:10 net
dr-x--x--x 2 test test 0 Sep 23 20:10 ns
-r--r--r-- 1 test test 0 Sep 23 20:10 numa_maps
-rw-r--r-- 1 test test 0 Sep 23 20:10 oom_adj
-r--r--r-- 1 test test 0 Sep 23 20:10 oom_score
-rw-r--r-- 1 test test 0 Sep 23 20:10 oom_score_adj
-r--r--r-- 1 test test 0 Sep 23 20:10 pagemap
-r-------- 1 test test 0 Sep 23 20:10 patch_state
-r--r--r-- 1 test test 0 Sep 23 20:10 personality
-rw-r--r-- 1 test test 0 Sep 23 20:10 projid_map
lrwxrwxrwx 1 test test 0 Sep 23 20:09 root -> /
-rw-r--r-- 1 test test 0 Sep 23 20:10 sched
-r--r--r-- 1 test test 0 Sep 23 20:10 schedstat
-r--r--r-- 1 test test 0 Sep 23 20:10 sessionid
-rw-r--r-- 1 test test 0 Sep 23 20:10 setgroups
-r--r--r-- 1 test test 0 Sep 23 20:10 smaps
-r--r--r-- 1 test test 0 Sep 23 20:10 stack
-r--r--r-- 1 test test 0 Sep 23 20:09 stat
-r--r--r-- 1 test test 0 Sep 23 20:10 statm
-r--r--r-- 1 test test 0 Sep 23 20:09 status
-r--r--r-- 1 test test 0 Sep 23 20:10 syscall
dr-xr-xr-x 3 test test 0 Sep 23 20:10 task
-r--r--r-- 1 test test 0 Sep 23 20:10 timers
-rw-r--r-- 1 test test 0 Sep 23 20:10 uid_map
-r--r--r-- 1 test test 0 Sep 23 20:10 wchan

上面演示了查看进程中文件的信息的方法,针对上面的信息,选两个来进行总结

lrwxrwxrwx 1 test test 0 Sep 23 20:09 cwd -> /home/test/process
lrwxrwxrwx 1 test test 0 Sep 23 20:09 exe -> /home/test/process/process

这里挑选出了两个内容,一个是cwd,一个是exe,选这两个也是有原因的,这两个可以挖掘出可值得学习的点

  1. cwd

在解决问题前要先知道什么是cwd,它的全程叫做current working directory,也就是所谓的当前工作目录,一般叫它叫当前目录,对于当前目录这个概念并不陌生,但什么是当前目录?

前面对于进程的定义中讲到,操作系统会创建出一个PCB来管理进入内存中的可执行程序,那么可执行程序是如何被管理的?该如何理解管理的概念?一个进程,要能找到自己的可执行程序,这样才能被称为管理起来,因此,这就意味着每一个进程都要有自己的工作目录,而默认情况下,进程启动的时候所处的路径就是当前路径

既然这是默认,那么当前路径也是可以更改的,有一个函数叫做chdir()函数,它的功能就是用以更变工作路径的,在Linux下使用man指令查看:

SYNOPSIS
       #include <unistd.h>

       int chdir(const char *path);
       int fchdir(int fd);

因此用实验来证明它的存在

对程序略做修改,让程序可以在工作目录下创建文件,可以使用C语言的文件操作来实现

#include <stdio.h>
#include <unistd.h>

int main()
{
    FILE* pf=fopen("test.txt","w");

    if(pf==NULL)
    {
        perror("fopen fail!\n");
        return 1;
    }

    fclose(pf);
    return 0;
}

编译运行结果,此时在process路径下就产生了一个test.txt文件,这也说明默认的工作路径就是进程启动的时候所处的环境,此时再看proc文件下的信息

[test@VM-16-11-centos process]$ ls /proc/3466 -l
total 0
lrwxrwxrwx 1 test test 0 Sep 23 21:17 cwd -> /home/test
lrwxrwxrwx 1 test test 0 Sep 23 21:17 exe -> /home/test/process/process

此时确实是被改变了,说明和前面是一样的

[test@VM-16-11-centos process]$ make
gcc -o process process.c
[test@VM-16-11-centos process]$ ./process
[test@VM-16-11-centos process]$ ll
total 20
-rw-rw-r-- 1 test test  106 Sep 23 19:39 Makefile
-rwxrwxr-x 1 test test 8464 Sep 23 20:47 process
-rw-rw-r-- 1 test test  203 Sep 23 20:45 process.c
-rw-rw-r-- 1 test test    0 Sep 23 20:47 test.txt

那么对于程序再略做修改

#include <stdio.h>
#include <unistd.h>

int main()
{
    chdir("/home/test");
    FILE* pf=fopen("test.txt","w");

    if(pf==NULL)
    {
        perror("fopen fail!\n");
        return 1;
    }

    fclose(pf);
    return 0;
}

此时将工作目录改到了家目录的一个文件夹下,此时再看test.txt的位置

[test@VM-16-11-centos ~]$ pwd
/home/test
[test@VM-16-11-centos ~]$ ll
-rw-rw-r--  1 test test    0 Sep 23 20:50 test.txt

此时程序生成的文件就默认创建到了这个文件夹内,此时打开/proc文件,再看进程的描述

  1. exe

exe表示的就是当前正在执行的可执行程序,如果把可执行程序从磁盘中删除

[test@VM-16-11-centos process]$ ll
total 20
-rw-rw-r-- 1 test test  106 Sep 23 19:39 Makefile
-rwxrwxr-x 1 test test 8520 Sep 23 19:46 process
-rw-rw-r-- 1 test test  187 Sep 23 19:46 process.c
[test@VM-16-11-centos process]$ rm process
[test@VM-16-11-centos process]$ ll
total 8
-rw-rw-r-- 1 test test 106 Sep 23 19:39 Makefile
-rw-rw-r-- 1 test test 187 Sep 23 19:46 process.c

但是程序依旧在运行,这是为什么?

这是因为,磁盘中的文件被删除了,其实和进程关系并不大,进程被运行前就已经被加载到内存中了,因此磁盘上文件的删除对于内存并不会造成决定性的影响,但是如果程序终止想要重新运行,可能就并不可以了,但是在proc文件内,会为用户标出错误提示,说明在磁盘中的可执行程序已经被删掉了

lrwxrwxrwx 1 test test 0 Sep 23 20:09 cwd -> /home/test/process
lrwxrwxrwx 1 test test 0 Sep 23 20:09 exe -> /home/test/process/process (deleted)

那么有几个问题就随之产生了:

  1. 这个父进程是谁,为什么一直不变?

对于这个问题,可以使用ps命令来查看,而结果是bash,也就是命令行解释器

[test@VM-16-11-centos process]$ ps ajx |head -1 && ps ajx | grep 7945
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 7944  7945  7945  7945 pts/0    16488 Ss    1003   0:00 -bash
  1. 父进程的概念如何理解?

关于这个问题,后续和fork一起总结

Linux中创建进程的方式通常有两种:

  1. 命令行中直接启动进程
  2. 通过代码来创建进程

对于第一种很好理解,执行程序./process其实就是启动进程,那第二种是什么?如何理解这个概念?就引出了本篇的核心,系统调用fork

启动进程,本质就是创建进程,一般都是通过父进程创建的

关于如何创建进程,下面用fork来讲述

fork

首先要对fork有一个初步认知,它可以给当前的进程添加一个子进程,它可以使用代码来创建进程,它是属于系统级别的调用:

  • 当用户启动一个进程的时候,如何理解在行为?其实就是在系统重多增加一个进程,操作系统要管理的进程就多了一个
  • 创建一个进程,就是要向系统中申请一些内存,保存当前进程的可执行程序并且要创建这个进程的PCB,也就是task_struct对象,并且将这个对象添加到进程列表中

那么如何来观察现象?

对程序进行改变

#include <stdio.h>
#include <unistd.h>

int main()
{
    printf("Before fork:the pid is %d,the ppid is %d\n",getpid(),getppid());

    fork();

    printf("After fork:the pid is %d,the ppid is %d\n",getpid(),getppid());

    return 0;
}

运行程序

# 运行程序
[test@VM-16-11-centos process]$ ./process 
# 运行结果
Before fork:the pid is 7810,the ppid is 6523
After fork:the pid is 7810,the ppid is 6523
After fork:the pid is 7811,the ppid is 7810

现象很神奇,程序中只打印了一次After fork...,但却输出了两次,并且第二次输出的结果的ppid就是第一次输出的pid,这是不是证明第二次输出的这个7811就是7810的子进程?

答案是肯定的,并且fork之后这两个进程都会执行它们自己的程序,由此展开关于fork的理解

fork的具体描述

使用man指令查看fork的帮助文档内的信息

NAME
       fork - create a child process

SYNOPSIS
       #include <unistd.h>

       pid_t fork(void);

从上面的表述中,可以获取到一些信息,fork的功能就是创建一个子进程,fork函数有两个返回值,给子进程返回0,给父进程返回子进程的pid

为什么要使用fork?

C语言中,写的代码的执行逻辑都是从上向下执行(默认情况下),但是事实上在一些情况下这样的需求满足不了用户的需求,例如要边下载一个电影边播放它,那么这个时候就需要创建一个子进程来帮助实现这个功能,这是单进程所解决不了的,因此级有了fork函数,有了这个函数可以让父进程和子进程做不一样的事,执行不一样的代码,通过fork的返回值就能判断谁是子进程谁是父进程,就可以让它们实现不同的代码片段,执行不同的功能

fork做了些什么?

从表面上看,fork函数在执行后,增加了一个进程,这个进程和原来的父进程会一起执行下去,分别在自己的进程下输出内容(以这个代码为例子),但是这都是表象,从深层次的角度来看,fork的实现过程并不简单

既然是子进程,也属于进程,是进程就要创建程序的PCB,那现在有了关于task_struct,里面的信息在哪里?拷贝的内容是什么?答案是以父进程为模板,为子进程创建PCB,而创建的PCB指向的可执行文件并没有创建,因此这里实现的子进程没有它自己的代码和数据,只是和父进程共享代码和数据,用下图来描述上面的这一系列过程如下:

在这里插入图片描述
上图清晰的把前文进行了图示化,创建出的子进程也有自己的PCB,内容来自于父进程的PCB,直接拷贝而来,而它的可执行文件是共享的父进程的可执行文件

fork之后,父子进程会执行同样的代码,fork之前的代码父子进程也都有记录

fork之后会执行同样的代码

  • fork之前的代码可以看到吗?可以看到,父子进程都有前面代码的数据

  • 子进程为什么不从头开始执行?这是由于pc/eip执行fork完毕后,eip指向的是fork后续的代码,eip也会被子进程继承,因此直接执行的是fork之后的代码

进程的独立性如何理解?

关于进程的独立性,可以从下面的角度入手,首先,进程独立性可以从每一个进程都有它自己的PCB来看出,进程之间是不会被相互影响的,但是数据父子是会被修改的,那么可以采用写实拷贝的方法来将这个过程执行下去,进程的代码可以共享,但是进程的数据不可以,数据每一个进程只能拥有一份,不然对于一些全局变量来说,一个进程对于全局变量的改变会使得另外一个进程受到严重的影响,因此上面的图其实并不完全正确,应该这样改良

在这里插入图片描述
新创建的子进程的PCB中,对于可执行文件的拥有应该分为两部分,代码片段和数据片段,对于代码片段可以进行共享,但是对于数据片段一定是每一个进程拥有一份独立的数据,这样才能保证进程的独立性

fork之后,父子进程谁先运行?

创建完成子进程,只是开始,系统中有其他进程,父进程和子进程,接下来谁先被执行要看谁先被调度,先被调度的就要先运行,那么有具体的规则吗?没有,这是由操作系统自己来决定的,由每个进程PCB中的调度信息,比如说时间片优先级等等,和调度器算法共同决定谁优先被调用

如何理解fork?

从本质上来讲,fork其实就是一个函数,那么它函数中的内容会有哪些?

  1. 找到父进程的PCB对象
  2. malloc一个PCB用来放子进程
  3. 用父进程的PCB来初始化子进程
  4. 让子进程的PCB指向父进程的代码和数据
  5. 子进程和父进程都加入调度队列开始排队

简单来说,就是创建子进程,将子进程放到调度队列中运行

以上为对fork的初步理解,后续会继续用它实现系统级别的代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1036845.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】list.h 常用函数实现详解

目录 一、概述二、基础函数✨2.1 INIT_LIST_HEAD✨2.2 list_empty 三、添加结点的函数✨3.1 __list_add✨3.2 list_add✨3.3 list_add_tail 四、删除结点的函数✨4.1 __list_del✨4.2 list_del 五、获取结构体指针、遍历链表✨5.1 list_entry✨5.2 list_for_each✨5.3 list_for…

如何让异步序列(AsyncSequence)优雅的感知被取消(Cancel)

概览 自  从 Swift 5.5 推出新的 async/await 并发模型以来&#xff0c;异步队列&#xff08;AsyncSequence&#xff09;就成为其中不可或缺的重要一员。 不同于普通的序列&#xff0c;异步序列有着特殊的“惰性”和并发性&#xff0c;若序列中的元素还未准备好&#xff0c…

BGP选路的十一条原则(第八课)

华为官网:有详细的BGP11条选路原则介绍 NetEngine AR 产品文档 (huawei.com) 第一 BGP 属性 第二 BGP 十一条选路原则 实操部分

5个小功能掌握正则表达式的使用

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ 这篇文章通过实现5个小功能&#xff0c;来讲述在Java中如何使用正则。 Java中如何使用正则 Java中正则相关类位于java.util.regex包下&#xff0c;主要使用2个类&#xff0…

【Maven入门篇】(1)详细讲解Maven的安装报错解决

&#x1f38a;专栏【Maven入门篇】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【The truth that you leave】 &#x1f970;欢迎并且感谢大家指出我的问题 文章目录 &#x1f33a;Maven介绍⭐作用⭐官网 &#x1f384;maven安…

mysql 5.7 修改密码

为了提高安全性 mysql5.7中user表的password字段已被取消&#xff0c;取而代之的事 authentication_string 字段&#xff0c;当然我们更改用户密码也不可以用原来的修改user表来实现了。下面简绍几种mysql5.7下修改root密码的方法&#xff08;其他用户也大同小异&#xff09;。…

整洁架构能有多整洁?

前段时间&#xff0c;我将一个中大型后端项目顺利地从Spring Boot 2.5 迁移到了Spring Boot 3&#xff0c;整个过程仅花了一天左右时间&#xff0c;在小酌庆祝之余&#xff0c;我开始思考此次迁移之所以能够顺利进行的原因&#xff0c;此时一个概念立即闪现脑海——整洁架构。 …

ARM Cortex-M内核中系统堆栈

文章目录 有无OS的栈结构区别&#xff1a;裸机的任务栈结构带FreeRTOS操作系统的任务栈 ARM的寄存器有哪些特殊寄存器有哪些 关于FreeRTOS中的SP寄存器栈操作【压栈与弹栈的操作】一般函数嵌套调用时sp指针的变化Cortex-M内核的MSP与PSP作用 有无OS的栈结构区别&#xff1a; 裸…

雷达设备问题(从另一个角度看待区间合并 + 贪心思路 + 未发现关键的错误样例)

雷达设备问题 文章目录 雷达设备问题前言题目描述题目分析代码详解错误案例分析&#xff1a;思路代码&#xff1a; 前言 对于区间合并问题&#xff0c;我们一般会将区间按照左端点或者是右端点进行排序&#xff0c;至于其中的选择要依据题目的分析&#xff0c;这里给大家用贪心…

Nginx 设置禁用 OPTIONS 请求

1、修改 nginx 配置 在 nginx.conf 配置文件中&#xff0c;增加如下内容&#xff1a; if ($request_method ~* OPTIONS) {return 403; }效果如下&#xff1a; 2、重启 nginx 服务 systemctl restart nginx或者 service nginx restart3、功能验证 使用如下命令&#xff…

【Java毕设项目】基于SpringBoot+Vue教务管理系统的开发与实现

博主主页&#xff1a;一季春秋博主简介&#xff1a;专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发&#xff0c;远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容&#xff1a;毕业设计(Java项目、小程序、安卓等)、简历模板、学习资料、…

提升群辉AudioStation音乐体验,实现公网音乐播放

文章目录 本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是本教程使用环境&#xff1a;1 群晖系统安装audiostation套件2 下载移动端app3 内网穿透&#xff0c;映射至公网 很多老铁想在上班路上听点喜欢的歌或者相声解解闷儿&#xff0c;于是打开手…

Unity WebSocket-Server

&#x1f33c;WebSocket-Server &#x1f96a;效果展示&#x1f32d;启动Server&#x1f371;连接Server &#x1f96a;效果展示 在Unity中创建WebSocket服务器&#xff0c;从网页连接到该服务器进行消息通信&#xff0c;在Unity中接收到的消息都在主线程中 &#x1f32d;启…

基于ssm的学生综合测评管理系统047

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…

C\C++ 设置Visual Studio编译器使用C++17标准

文章作者&#xff1a;里海 来源网站&#xff1a;王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C-CSDN博客 简介&#xff1a; 使用ISO C17标准可以为开发人员带来许多好处&#xff0c;包括更简洁的代码、更高的运行效率、更好的硬件支持、更好的兼容性和可移植性&am…

基于springboot+vue的重庆旅游网(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

二、逻辑回归算法(LR,Logistic Regression)(有监督学习)

一、算法思路 逻辑回归本质就是基于多元线性回归&#xff0c;多元线性回归就是yw0 w1*x1 w2*x2 ... wn*xn 多元函数的值域是(-∞&#xff0c;∞)&#xff0c;逻辑回归就是将值域映射到(0,1)之间&#xff0c;因为这样就可以变成一个概率值。常用的方法是将多元函数求解得到…

vscode调试webpack项目的方法

vscode调试webpack项目的方法 首先安装vscode插件Javascript Debugger 这个插件的介绍也写清楚了&#xff1a; An extension for debugging Node.js programs and Chrome. 那就是用来调试Node.js和Chrome的vscode扩展插件&#xff0c;包括typescript. 然后按F5启动调试&…

【LeetCode-简单题】589. N 叉树的前序遍历

文章目录 题目方法一&#xff1a;单循环栈做法方法二&#xff1a;递归 题目 方法一&#xff1a;单循环栈做法 关键在于子节点的入栈顺序&#xff0c;决定了子节点的出栈顺序&#xff0c; 因为是前序遍历 所以压栈顺序先让右边的入栈 依次往左 这样左边的节点会在栈顶 这样下次…

Linux CentOS7 vim多文件编辑

使用vim编辑多个文件&#xff0c;十分常用的操作。本文从打开、显示、切换文件到退出&#xff0c;进行简单讨论。 一、打开文件 1.一次打开多个文件 vim还没有启动的时候&#xff0c;在终端里输入vim file1 file2 … filen便可以打开所有想要打开的文件。 执行命令 vim fil…