Linux篇【5】:Linux 进程概念(二)

news/2024/5/14 8:34:52/文章来源:https://blog.csdn.net/lcc11223/article/details/127800569

目录

3.5、查看进程

3.6、通过系统调用接口获取正在进行的进程的标识符

3.7、通过系统调用接口创建子进程 - fork 初识


3.5、查看进程

[HJM@hjmlcc ~]$ clear
[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
[HJM@hjmlcc ~]$ touch mytest.c
[HJM@hjmlcc ~]$ ls
mytest.c
[HJM@hjmlcc ~]$ touch Makefile
[HJM@hjmlcc ~]$ ls
Makefile  mytest.c
[HJM@hjmlcc ~]$ vim Makefile
[HJM@hjmlcc ~]$ cat Makefile
mytest:mytest.cgcc mytest.c -o mytest.PHONY:clean
clean:rm -f mytest
[HJM@hjmlcc ~]$ vim mytest.c
[HJM@hjmlcc ~]$ cat mytest.c
#include<stdio.h>
#include<unistd.h>
int main()
{while(1)        //死循环、{printf("I am a process!\n");sleep(1);}return 0;
}
[HJM@hjmlcc ~]$ make
gcc mytest.c -o mytest
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
//此处的 mytest 是可执行程序,是一个普通文件,存在于磁盘上,该磁盘指的并不是在我们笔记本中的磁
//盘上,而是存在于云服务器上的磁盘中、
[HJM@hjmlcc ~]$ ldd mytestlinux-vdso.so.1 =>  (0x00007ffcba19d000)/$LIB/libonion.so => /lib64/libonion.so (0x00007f18b638f000)libc.so.6 => /lib64/libc.so.6 (0x00007f18b5ea8000)libdl.so.2 => /lib64/libdl.so.2 (0x00007f18b5ca4000)/lib64/ld-linux-x86-64.so.2 (0x00007f18b6276000)
[HJM@hjmlcc ~]$ file mytest
mytest: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=e1ce1242da6edeb0fd0c5a1c316cbd303ba05c73, not stripped
[HJM@hjmlcc ~]$ ./mytest   
//之前我们称上述操作为将可执行程序mytest运行起来,现在通过上述操作便可形成一个进程,因此我们可
//以称上述操作是:一个关于可执行程序mytest所形成的进程、
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
...
...

在 Linux 操作系统中,如何查看正在运行(时实启动)的进程及其信息呢?

方法一:

[HJM@hjmlcc ~]$ clear
[HJM@hjmlcc ~]$ ps ajx   //a:all,j:job,x:以特定格式进行显示、
//把 Linux 操作系统中所有的正在运行的时实启动的进程及其信息全部显示出来、PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND0     1     1     1 ?           -1 Ss       0  17:46 /usr/lib/sys0     2     0     0 ?           -1 S        0   0:03 [kthreadd]2     4     0     0 ?           -1 S<       0   0:00 [kworker/0:02    18     0     0 ?           -1 S        0   0:00 [kdevtmpfs]2    19     0     0 ?           -1 S<       0   0:00 [netns]2    20     0     0 ?           -1 S        0   0:02 [khungtaskd]
...
...2 30148     0     0 ?           -1 S        0   0:00 [kworker/0:11 30373 30373 30373 ?           -1 Ssl   1002   0:00 /home/HJM/.V1 30380 30380 30380 ?           -1 Ssl   1002   0:00 /home/HJM/.V
30380 30391 30380 30380 ?           -1 Z     1002   0:00 [querydb] <d1 31068 31068 31068 ?           -1 Ssl   1002   0:00 /home/HJM/.V1 31076 31076 31076 ?           -1 Ssl   1002   0:00 /home/HJM/.V
31076 31087 31076 31076 ?           -1 Z     1002   0:00 [querydb] <d2 31438     0     0 ?           -1 S        0   0:00 [kworker/0:32 32544     0     0 ?           -1 S        0   0:01 [kworker/0:0
[HJM@hjmlcc ~]$ ps ajx | grep 'mytest'
10484 12399 12399 10484 pts/0    12399 S+    1002   0:00 ./mytest
12404 13061 13060 12404 pts/1    13060 S+    1002   0:00 grep --color=automytest
//在Linux操作系统中所有的正在运行的时实启动的进程及其信息中查找关于可执行程序mytest所形成的
//进程及其信息,若关于可执行程序mytest所形成的进程正在运行或时实启动,则会把关于可执行程序mytes
//t所形成的进程及其信息显式出来,若关于可执行程序mytest所形成的进程未正在运行或未时实启动,则
//不会把关于可执行程序mytest所形成的进程及其信息显式出来、//对于上述指令行而言,有关可执行程序ps所形成的进程和有关可执行程序grep所形成的进程一直都是在
//运行(时实启动)的,有关可执行程序mytest所形成的进程可能正在运行(时实启动),也有可能没有正在运
//行(时实启动),由于上面是对有关可执行程序mytest形成的进程及其信息进行的搜索,按理说只需要显式
//出来有关可执行程序mytest形成的进程是否正在运行(时实启动)即可,但此处还把正在运行(时实启动)
//的有关可执行程序grep所形成的进程及其信息显示了出来,其次,虽然这里并未显式出来正在运行(时实
//启动的)有关可执行程序ps所形成的进程及其信息,但要知道,有关可执行程序ps所形成的进程一直正在
//运行(时实启动),只不过这里并没有把该进程及其信息显式出来而已,由于此处还默认显式出来正在运行
//(时实启动的)有关可执行程序grep所形成的进程及其信息,若不想显式该进程及其信息的话,可以通过下
//述操作:
[HJM@hjmlcc ~]$ ps ajx | grep 'mytest' | grep -v grep
//即:上述操作中grep -v的后面只要匹配到某一个有关某一个可执行程序所形成的进程所对应的可执行程
//序的名字,则该进程及其信息一律不进行显式,此时我们知道,对于有关可执行程序grep所形成的进程而
//言是一直在运行(时实启动)的,按理说在下面会显示出来该进程及其信息,但是,上述操作中又有grep -v
// grep,所以在下面结果中就不再进行显示该进程及其信息了、
10484 23680 23680 10484 pts/0    23680 S+    1002   0:00 ./mytest
[HJM@hjmlcc ~]$ 

    我们自己写的程序代码,当经过编译链接之后则形成一个可执行程序,运行该可执行程序之后就得到一个进程,同样,别人写的程序代码当编译链接之后也会形成一个可执行程序,运行该可执行程序之后也得到一个进程,比如:ls,pwd,touch,grep,chgrp,chown,mkdir,rm ... 等等指令,这些指令在本质上就是可执行程序,当我们执行这些指令时,本质上就是运行了这些可执行程序,因此当运行这些可执行程序时,也会得到这些可执行程序各自对应的进程,Linux 系统中的大部分指令(可执行程序)存在于云服务器中的磁盘里面,可以通过指令:ls /usr/bin/* 查看,如下所示,这些大部分指令(可执行程序)就等价于 Windows 系统中 C 盘里的应用程序(可执行程序)、

[HJM@hjmlcc ~]$ ls /usr/bin/*
//usr:用户,bin:二进制、
/usr/bin/[
/usr/bin/a2p
/usr/bin/abrt-action-analyze-backtrace
/usr/bin/abrt-action-analyze-c
/usr/bin/abrt-action-analyze-ccpp-local
/usr/bin/abrt-action-analyze-core
/usr/bin/abrt-action-analyze-oops
/usr/bin/abrt-action-analyze-python
/usr/bin/abrt-action-analyze-vmcore
/usr/bin/abrt-action-analyze-vulnerability
/usr/bin/abrt-action-analyze-xorg
/usr/bin/abrt-action-check-oops-for-hw-err
...
...
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit
/usr/bin/zless
/usr/bin/zmore
/usr/bin/znew
/usr/bin/zsoelim
[HJM@hjmlcc ~]$ //之前我们执行的所有的指令,本质上都是在运行可执行程序,则都会形成这些可执行程序对应的进程,只不
//过像:ls,pwd等等这些指令,在执行时,也相当于在运行可执行程序,因此则都会形成他们对应的进程,但
//是他们对应的进程的生命周期很短就结束了,即当我执行完这些指令时,由这些指令所形成的进程很快就
//结束了,在我通过方法查看正在运行或时实启动的进程及其信息之前,由这些指令所形成的进程就已经结
//束了,所以当在查看正在运行或时实启动的进程及其信息时,就看不到由这些指令所形成的进程及其信
//息了、//在 Windows 系统中,当我们双击 CF 的快捷方式,而该快捷方式指向了 CF 的可执行程序,所以就相当
//于在双击 CF 的可执行程序,即就相当于在运行 CF 的可执行程序,因此便形成了一个与它对应的进程,
//就可以愉快的玩游戏了、

方法二:

    操作系统是进程的管理者,每一个正在运行(时实启动)的进程在 Linux 操作系统中都会存在唯一的一个与之对应的标识符,这个唯一的标识符就是所谓的 PID ,即:Process ID 、

[HJM@hjmlcc ~]$ ps ajx | grep 'mytest'
12404  3406  3405 12404 pts/1     3405 S+    1002   0:00 grep --color=auto mytest
10484 31395 31395 10484 pts/0    31395 S+    1002   0:00 ./mytest
[HJM@hjmlcc ~]$ ps ajx | grep 'mytest' | grep -v grep
10484 31395 31395 10484 pts/0    31395 S+    1002   0:00 ./mytest
[HJM@hjmlcc ~]$ ps ajx | head -1       //是1不是l,代表前1行、PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
[HJM@hjmlcc ~]$ ps ajx | head -5
//把 Linux 操作系统中所有的正在运行的时实启动的进程及其信息的前 5 行全部显示出来,其中第一行
//代表进程属性的名称、PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND0     1     1     1 ?           -1 Ss       0  17:59 /usr/lib/systemd/systemd --system --deserialize 230     2     0     0 ?           -1 S        0   0:03 [kthreadd]2     4     0     0 ?           -1 S<       0   0:00 [kworker/0:0H]2     6     0     0 ?           -1 S        0   2:20 [ksoftirqd/0]
[HJM@hjmlcc ~]$ ps ajx | head -1 && ps ajx | grep 'mytest' | grep -v grep
//当指令行:ps ajx | head -1执行成功后,再执行指令行:head -1 && ps ajx | grep 'mytest' | grep
// -v grep,若前面的指令行执行失败,则后面的指令行就不再进行执行了、PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
10484 31395 31395 10484 pts/0    31395 S+    1002   0:00 ./mytest
//由此可知,有关可执行程序mytest所形成的进程的 PID 是31395、
[HJM@hjmlcc ~]$ ls /proc/31395
attr        cmdline          environ  io         mem         ns             pagemap      sched      stack    task
autogroup   comm             exe      limits     mountinfo   numa_maps      patch_state  schedstat  stat     timers
auxv        coredump_filter  fd       loginuid   mounts      oom_adj        personality  sessionid  statm    uid_map
cgroup      cpuset           fdinfo   map_files  mountstats  oom_score      projid_map   setgroups  status   wchan
clear_refs  cwd              gid_map  maps       net         oom_score_adj  root         smaps      syscall
[HJM@hjmlcc ~]$ ls /proc/31395 -d
/proc/31395//此时如果把有关可执行程序mytest所形成的进程结束掉,然后再执行指令:ls /proc/31395 -d时,得到
//如下结果,这是因为,根目录下的proc目录中存放的是当前 Linux 操作系统中正在运行或时实启动的进
//程及其信息、
[HJM@hjmlcc ~]$ ls /proc/31395 -d
ls: cannot access /proc/31395: No such file or directory
[HJM@hjmlcc ~]$ //当把有关可执行程序mytest所形成的进程再次启动时,若再执行上述指令:ls /proc/31395 -d,会发现
//得到的结果是:ls: cannot access /proc/31395: No such file or directory,如下所示:
[HJM@hjmlcc ~]$ ls /proc/31395 -d
ls: cannot access /proc/31395: No such file or directory
[HJM@hjmlcc ~]$ ps ajx | grep 'mytest' | grep -v grep
10484 27073 27073 10484 pts/0    27073 S+    1002   0:00 ./mytest
[HJM@hjmlcc ~]$ ps ajx | head -1 && ps ajx | grep 'mytest' | grep -v grepPPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
10484 27073 27073 10484 pts/0    27073 S+    1002   0:00 ./mytest
//这是因为:当我们重新启动有关可执行程序mytest所形成的进程时,此次的该进程与前一次启动有关可执行
//程序mytest所形成的进程并不是同一个进程,后者相对于前者而言是一个新的进程,所以此次的有关可执
//行程序mytest所形成的进程的 PID 也会发生改变,Linux 操作系统会为其重新分配 PID ,由31395变成
//了27073、
[HJM@hjmlcc ~]$ ls /proc/27073 -d
/proc/27073
[HJM@hjmlcc ~]$ ls /proc/27073
//以下则是有关可执行程序mytest所形成的进程的所有的属性数据信息的集合,时实的以文件的方式进行
//显示、
attr        cmdline          environ  io         mem         ns             pagemap      sched      stack    task
autogroup   comm             exe      limits     mountinfo   numa_maps      patch_state  schedstat  stat     timers
auxv        coredump_filter  fd       loginuid   mounts      oom_adj        personality  sessionid  statm    uid_map
cgroup      cpuset           fdinfo   map_files  mountstats  oom_score      projid_map   setgroups  status   wchan
clear_refs  cwd              gid_map  maps       net         oom_score_adj  root         smaps      syscall
[HJM@hjmlcc ~]$ ls /proc/27073 -al
total 0
dr-xr-xr-x   9 HJM  HJM  0 Nov 12 19:09 .
dr-xr-xr-x 124 root root 0 Jul 28 11:13 ..
dr-xr-xr-x   2 HJM  HJM  0 Nov 12 19:15 attr
-rw-r--r--   1 HJM  HJM  0 Nov 12 19:15 autogroup
-r--------   1 HJM  HJM  0 Nov 12 19:15 auxv
-r--r--r--   1 HJM  HJM  0 Nov 12 19:15 cgroup
--w-------   1 HJM  HJM  0 Nov 12 19:15 clear_refs
-r--r--r--   1 HJM  HJM  0 Nov 12 19:09 cmdline
-rw-r--r--   1 HJM  HJM  0 Nov 12 19:15 comm
-rw-r--r--   1 HJM  HJM  0 Nov 12 19:15 coredump_filter
-r--r--r--   1 HJM  HJM  0 Nov 12 19:15 cpuset
lrwxrwxrwx   1 HJM  HJM  0 Nov 12 19:09 cwd -> /home/HJM
//上述代表有关可执行程序mytest所形成的的进程当前的工作路径、
-r--------   1 HJM  HJM  0 Nov 12 19:09 environ
lrwxrwxrwx   1 HJM  HJM  0 Nov 12 19:09 exe -> /home/HJM/mytest
//上述代表的就是有关可执行程序mytest所形成的的进程对应的在云服务器中的磁盘中的可执行程序mytes
//t所在的路径、
...
...
-r--r--r--   1 HJM  HJM  0 Nov 12 19:15 statm
-r--r--r--   1 HJM  HJM  0 Nov 12 19:09 status
-r--r--r--   1 HJM  HJM  0 Nov 12 19:15 syscall
dr-xr-xr-x   3 HJM  HJM  0 Nov 12 19:15 task
-r--r--r--   1 HJM  HJM  0 Nov 12 19:15 timers
-rw-r--r--   1 HJM  HJM  0 Nov 12 19:15 uid_map
-r--r--r--   1 HJM  HJM  0 Nov 12 19:15 wchan
[HJM@hjmlcc ~]$ //进程的 PID 以及当前路径等等都属于进程的属性数据信息,都属于系统数据,都在描述该进程的进程控
//制块(PCB),在 Linux 系统下的 task_struct 结构体中、//在之前,我们认为当前路径就是程序或者源代码所在的路径,其实本质上并不准确,真正意义上的当前路径
//指的就是:进程当前所在(工作)的路径,当进程启动时,这个路径由进程自己进行维护、//如下所示:    
//新建会话0:
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ cat mytest.c
#include<stdio.h>
#include<unistd.h>
int main()
{FILE* fp=fopen("log.txt","w");//由此可知,log.txt前面并没有指定路径,则默认为当前路径下,如果在当前路径下不存在普通文//件log.txt,则会新建一个名为log.txt的普通文件、while(1){printf("I am a process!\n");sleep(1);}return 0;
}
[HJM@hjmlcc ~]$ make
gcc mytest.c -o mytest
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ mv mytest code  
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ cd code
[HJM@hjmlcc code]$ ls
mytest
[HJM@hjmlcc code]$ ./mytest
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
...
...//新建会话1:
[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ cd code
[HJM@hjmlcc code]$ ls
mytest
[HJM@hjmlcc code]$ ps ajx | head -1 && ps ajx | grep 'mytest' | grep -v grepPPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
10484  1738  1738 10484 pts/0     1738 S+    1002   0:00 ./mytest
[HJM@hjmlcc code]$ ls /proc/1738
attr             environ    mem            pagemap      stack
autogroup        exe        mountinfo      patch_state  stat
auxv             fd         mounts         personality  statm
cgroup           fdinfo     mountstats     projid_map   status
clear_refs       gid_map    net            root         syscall
cmdline          io         ns             sched        task
comm             limits     numa_maps      schedstat    timers
coredump_filter  loginuid   oom_adj        sessionid    uid_map
cpuset           map_files  oom_score      setgroups    wchan
cwd              maps       oom_score_adj  smaps
[HJM@hjmlcc code]$ ls /proc/1738 -d
/proc/1738
[HJM@hjmlcc code]$ ls /proc/1738 -al
total 0
dr-xr-xr-x   9 HJM  HJM  0 Nov 12 19:44 .
dr-xr-xr-x 126 root root 0 Jul 28 11:13 ..
dr-xr-xr-x   2 HJM  HJM  0 Nov 12 19:45 attrer
-r--r--r--   1 HJM  HJM  0 Nov 12 19:45 cpuset
lrwxrwxrwx   1 HJM  HJM  0 Nov 12 19:44 cwd -> /home/HJM/code         //当前路径、
-r--------   1 HJM  HJM  0 Nov 12 19:45 environ
lrwxrwxrwx   1 HJM  HJM  0 Nov 12 19:44 exe -> /home/HJM/code/mytest
lrwxrwxrwx   1 HJM  HJM  0 Nov 12 19:44 root -> /
-rw-r--r--   1 HJM  HJM  0 Nov 12 19:45 sched
...
...
-r--r--r--   1 HJM  HJM  0 Nov 12 19:45 syscall
dr-xr-xr-x   3 HJM  HJM  0 Nov 12 19:45 task
-r--r--r--   1 HJM  HJM  0 Nov 12 19:45 timers
-rw-r--r--   1 HJM  HJM  0 Nov 12 19:45 uid_map
-r--r--r--   1 HJM  HJM  0 Nov 12 19:45 wchan
[HJM@hjmlcc ~]$ //新建会话0:
...
...
I am a process!
I am a process!
I am a process!
I am a process!
I am a process!
^C
[HJM@hjmlcc code]$ ls
log.txt  mytest//注意:
//1、
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ cd code
[HJM@hjmlcc code]$ ls
[HJM@hjmlcc code]$ cd ..
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ make
gcc mytest.c -o mytest
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ make clean
rm -f mytest
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ //2、
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ cd code
[HJM@hjmlcc code]$ ls
[HJM@hjmlcc code]$ cd ..
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ make
gcc mytest.c -o mytest
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ mv mytest code
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ cd code
[HJM@hjmlcc code]$ ls
mytest
[HJM@hjmlcc code]$ make clean
make: *** No rule to make target `clean'.  Stop.   //无法删除可执行程序mytest、
[HJM@hjmlcc code]$ cd ..
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ make clean
rm -f mytest
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ cd code
[HJM@hjmlcc code]$ ls
mytest                           //仍没有删除掉可执行程序mytest、
[HJM@hjmlcc code]$ 
//在讲解粘滞位时,tmp目录文件是一个共享的目录文件,里面存放的是临时文件、
//proc目录文件是 Linux 系统根目录下的一个目录,proc:process,proc:内存文件系统,该目录文件中存
//放的是当前操作系统中正在运行或时实运行的进程及其信息、
[HJM@hjmlcc ~]$ ls /
bin  boot  data  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[HJM@hjmlcc ~]$ [HJM@hjmlcc ~]$ ls /
bin  boot  data  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[HJM@hjmlcc ~]$ ls /proc
1      12535  16515  20344  25287  28     31335  50    7          cpuinfo      irq         modules       swaps
10     13     16526  20730  255    29     31368  51    8          crypto       kallsyms    mounts        sys
10470  1389   16792  20827  256    290    36     52    8227       devices      kcore       mtrr          sysrq-trigger
10483  1390   18     21     26     291    37     577   9          diskstats    keys        net           sysvipc
10484  14     18820  21813  262    292    3756   6     925        dma          key-users   pagetypeinfo  timer_list
11     1521   18853  22     266    29633  38     646   991        driver       kmsg        partitions    timer_stats
1164   1552   19     23     267    30123  387    648   993        execdomains  kpagecount  sched_debug   tty
1178   1558   19039  24     269    30373  3871   65    acpi       fb           kpageflags  schedstat     uptime
12     1559   19089  24315  27     30380  39     651   buddyinfo  filesystems  loadavg     scsi          version
1207   1575   197    2472   270    30391  4      6515  bus        fs           locks       self          vmallocinfo
1222   16     2      2485   27176  31068  407    652   cgroups    interrupts   mdstat      slabinfo      vmstat
12404  160    20     2496   27184  31076  47     654   cmdline    iomem        meminfo     softirqs      xpmem
12524  16503  20337  25     27195  31087  49     659   consoles   ioports      misc        stat          zoneinfo
[HJM@hjmlcc ~]$ ls /proc -l
total 0
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 1
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 10
dr-xr-xr-x  9 root           root                         0 Nov 12 14:59 10470
dr-xr-xr-x  9 HJM            HJM                          0 Nov 12 14:59 10483
dr-xr-xr-x  9 HJM            HJM                          0 Nov 12 14:59 10484
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 11
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 1164
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 1178
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 12
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 1207
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 8
dr-xr-xr-x  9 root           root                         0 Nov 12 14:48 8227
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 9
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 925
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 991
dr-xr-xr-x  9 root           root                         0 Jul 28 11:13 993
dr-xr-xr-x  2 root           root                         0 Nov 12 16:47 acpi
-r--r--r--  1 root           root                         0 Nov 12 16:47 buddyinfo
dr-xr-xr-x  4 root           root                         0 Nov 12 16:47 bus
-r--r--r--  1 root           root                         0 Nov 12 16:47 cgroups
-r--r--r--  1 root           root                         0 Nov 12 16:47 cmdline
-r--r--r--  1 root           root                         0 Nov 12 16:47 consoles
-r--r--r--  1 root           root                         0 Nov 12 16:47 cpuinfo
-r--r--r--  1 root           root                         0 Nov 12 16:47 crypto
-r--r--r--  1 root           root                         0 Nov 12 16:47 devices
...
...
-r--r--r--  1 root           root                         0 Nov 12 16:47 version
-r--------  1 root           root                         0 Nov 12 16:47 vmallocinfo
-r--r--r--  1 root           root                         0 Nov 12 16:47 vmstat
dr-xr-xr-x  2 root           root                         0 Nov 12 16:47 xpmem
-r--r--r--  1 root           root                         0 Nov 12 16:47 zoneinfo
[HJM@hjmlcc ~]$ 

拓展:

[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
//显式出当前路径(目录)下的所有内容、
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ls /            //此处的 / 代表根目录、
//显示出根目录下的所有内容、
bin  boot  data  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[HJM@hjmlcc ~]$ ls /proc        //此处的 / 代表根目录、
//显示出根目录下的proc目录中的所有内容、
1      12535  16515  20344  25287  28     36    52    7          cpuinfo      irq         modules       swaps
10     13     16526  20730  255    29     37    577   8          crypto       kallsyms    mounts        sys
10470  1389   16792  20827  256    290    3756  6     8227       devices      kcore       mtrr          sysrq-trigger
10483  1390   18     21     26     291    38    646   9          diskstats    keys        net           sysvipc
10484  14     18820  21813  262    292    387   648   925        dma          key-users   pagetypeinfo  timer_list
11     1521   18853  22     266    30373  3871  65    991        driver       kmsg        partitions    timer_stats
1164   1552   19     23     267    30380  39    650   993        execdomains  kpagecount  sched_debug   tty
1178   1558   19039  24     269    30391  4     651   acpi       fb           kpageflags  schedstat     uptime
12     1559   19089  24315  27     31068  407   6515  buddyinfo  filesystems  loadavg     scsi          version
1207   1575   197    2472   270    31076  47    652   bus        fs           locks       self          vmallocinfo
1222   16     2      2485   27176  31087  49    654   cgroups    interrupts   mdstat      slabinfo      vmstat
12404  160    20     2496   27184  31395  50    659   cmdline    iomem        meminfo     softirqs      xpmem
12524  16503  20337  25     27195  32061  51    678   consoles   ioports      misc        stat          zoneinfo
[HJM@hjmlcc ~]$ ls /home/HJM       //此处只有第一个 / 代表根目录、
//显示出根目录下的home目录下的HJM目录中的所有内容、
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ 
// cd 指令的用法也类似于上面所示、

3.6、通过系统调用接口获取正在进行的进程的标识符

    通过Linux操作系统所提供的系统调用接口获取正在进行(时实启动)的进程的进程ID(PID)和该进程的父进程ID(PPID)、

如何获取正在运行(时实启动)的进程的 PID 呢 ?

//当启动一个进程,则该进程就是正在运行(时实启动)的,则操作系统会为该进程分配一个 PID 、
[HJM@hjmlcc ~]$ man 2 getpid  //查看Linux操作系统提供的系统调用接口、
//由于Linux操作系统是使用C语言写的,故Linux操作系统所提供的系统调用接口在本质上就是C语言函数
//调用接口,这属于Linux操作系统的系统调用接口,在Windows系统下使用该Linux系统下的该系统调用
//接口,应该是不可以的、 
GETPID(2)                     Linux Programmer's Manual                       GETPID(2)                                              NAMEgetpid, getppid - get process identificationSYNOPSIS#include <sys/types.h>#include <unistd.h>pid_t getpid(void);   // pid_t 等价于 size_t 、pid_t getppid(void);DESCRIPTIONgetpid() returns the process ID of the calling process.  (This is often used by routines that generate unique temporary filenames.)getppid() returns the process ID of the parent of the calling process.ERRORSThese functions are always successful.CONFORMING TOPOSIX.1-2001, 4.3BSD, SVr4.NOTESSince  glibc  version  2.3.4,  the glibc wrapper function for getpid() caches PIDs, so as to avoid additional system calls when a process callsgetpid() repeatedly.  Normally this caching is invisible, but its correct operation relies on support in the  wrapper  functions  for  fork(2),vfork(2),  and  clone(2):  if an application bypasses the glibc wrappers for these system calls by using syscall(2), then a call to getpid() inthe child will return the wrong value (to be precise: it will return the PID of the parent process).  See also clone(2)  for  discussion  of  acase where getpid() may return the wrong value even when invoking clone(2) via the glibc wrapper function.SEE ALSOclone(2), fork(2), kill(2), exec(3), mkstemp(3), tempnam(3), tmpfile(3), tmpnam(3), credentials(7)COLOPHONThis  page  is part of release 3.53 of the Linux man-pages project.  A description of the project, and information about reporting bugs, can befound at http://www.kernel.org/doc/man-pages/.Manual page getpid(2) line 1 (press h for help or q to quit)q
//新建会话0:
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest.c
[HJM@hjmlcc ~]$ vim mytest.c
[HJM@hjmlcc ~]$ cat mytest.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{while(1){printf("I am a process!,pid:%d\n",getpid());sleep(1);}return 0;
}
[HJM@hjmlcc ~]$ make
gcc mytest.c -o mytest
[HJM@hjmlcc ~]$ ls
code  Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ./mytest
I am a process!,pid:9457
I am a process!,pid:9457
I am a process!,pid:9457
I am a process!,pid:9457
I am a process!,pid:9457
I am a process!,pid:9457
...
...//新建会话1:
[HJM@hjmlcc ~]$ ps ajx | head -1 && ps ajx | grep 'mytest' | grep -v grepPPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND5899  9457  9457  5899 pts/0     9457 S+    1002   0:00 ./mytest         //9457、
[HJM@hjmlcc ~]$ 

如何结束掉正在运行(时实启动)的进程呢?

方法一:

[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ./mytest
I am a process!,pid:10001
I am a process!,pid:10001
I am a process!,pid:10001
I am a process!,pid:10001
I am a process!,pid:10001
I am a process!,pid:10001
I am a process!,pid:10001
^C
[HJM@hjmlcc ~]$ 
//使用热键 ctrl+c ,即可结束掉正在运行(时实启动)的进程、

方法二:

//新建会话0:
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ./mytest
I am a process!,pid:10470
I am a process!,pid:10470
I am a process!,pid:10470
I am a process!,pid:10470
...
...//新建会话1:
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ kill -9 10470
//向正在运行(时实启动)的进程发送9号信号,在后期信号中会进行具体的阐述,10470就是我们要结束掉的
//正在运行(时实启动)的进程的PID、
[HJM@hjmlcc ~]$ //新建会话0:
...
...
I am a process!,pid:10470
I am a process!,pid:10470
I am a process!,pid:10470
I am a process!,pid:10470
Killed
[HJM@hjmlcc ~]$ 
//此时正在运行(时实启动)的有关可执行程序mytest所形成的进程就被结束掉了、
[HJM@hjmlcc ~]$ man 2 getppid
GETPID(2)               Linux Programmer's Manual               GETPID(2)NAMEgetpid, getppid - get process identificationSYNOPSIS#include <sys/types.h>#include <unistd.h>pid_t getpid(void);pid_t getppid(void);DESCRIPTIONgetpid()  returns the process ID of the calling process.  (This isoften used by routines that generate unique temporary filenames.)getppid() returns the process ID of  the  parent  of  the  callingprocess.ERRORSThese functions are always successful.CONFORMING TOPOSIX.1-2001, 4.3BSD, SVr4.NOTESSince glibc version 2.3.4, the glibc wrapper function for getpid()caches PIDs, so as to avoid additional system calls when a processcalls  getpid()  repeatedly.   Normally this caching is invisible,but its correct operation relies on support in the  wrapper  func‐tions  for  fork(2),  vfork(2),  and  clone(2):  if an applicationbypasses the glibc  wrappers  for  these  system  calls  by  usingsyscall(2),  then  a call to getpid() in the child will return thewrong value (to be precise: it will return the PID of  the  parentprocess).   See  also clone(2) for discussion of a case where get‐pid() may return the wrong value even when invoking  clone(2)  viaManual page getppid(2) line 1 (press h for help or q to quit)q
//新建会话0:
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ cat mytest.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{while(1){printf("I am a process!,pid:%d,ppid:%d\n",getpid(),getppid());sleep(1);}return 0;
}
[HJM@hjmlcc ~]$ make
gcc mytest.c -o mytest
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ./mytest
//有关可执行程序mytest所形成的进程的进程ID(PID)为12260,而该进程的父进程ID(PPID)为5899、
I am a process!,pid:12260,ppid:5899
I am a process!,pid:12260,ppid:5899
I am a process!,pid:12260,ppid:5899
I am a process!,pid:12260,ppid:5899
I am a process!,pid:12260,ppid:5899
...
...//新建会话1:
[HJM@hjmlcc ~]$ ps ajx | head -1 && ps ajx | grep 'mytest' | grep -v grepPPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND5899 12260 12260  5899 pts/0    12260 S+    1002   0:00 ./mytest
[HJM@hjmlcc ~]$ //先把本次有关可执行程序mytest所形成的进程结束掉,然后再重新启动有关可执行程序mytest所形成的
//进程:
//新建会话0:
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ./mytest
//有关可执行程序mytest所形成的进程的进程ID(PID)为13359,而该进程的父进程ID(PPID)为5899、
I am a process!,pid:13359,ppid:5899
I am a process!,pid:13359,ppid:5899
I am a process!,pid:13359,ppid:5899
I am a process!,pid:13359,ppid:5899
...
...//新建会话1:
[HJM@hjmlcc ~]$ ps ajx | head -1 && ps ajx | grep 'mytest' | grep -v grepPPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND5899 13359 13359  5899 pts/0    13359 S+    1002   0:00 ./mytest
[HJM@hjmlcc ~]$ //由上可知,当我们每一次结束掉上一次有关可执行程序mytest所形成的进程,然后再重新启动有关可执行
//程序mytest所形成的进程时,会发现,这多个由有关可执行程序mytest所形成的进程中的进程ID(PID)都
//不相同,但是这多个由有关可执行程序mytest所形成的进程中的父进程ID(PPID)则都相同、//不管有关可执行程序mytest所形成的进程是否正在运行(时实启动),而该进程的父进程则都是一直正在
//运行(时实启动)的、//新建会话0:
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ./mytest
I am a process!,pid:15708,ppid:5899
I am a process!,pid:15708,ppid:5899
I am a process!,pid:15708,ppid:5899
...
...//新建会话1:
[HJM@hjmlcc ~]$ ps ajx | head -1 && ps ajx | grep 5899PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND5898  5899  5899  5899 pts/0    15708 Ss    1002   0:00 -bash       
//上述进程的进程ID(PID)为5899,这也就是有关可执行程序mytest所形成的进程的父进程、
//几乎我们在命令行上所执行的所有的指令,包括运行我们自己编写的程序代码所形成的可执行程序,所形
//成的进程都是bash进程的子进程、5899 15708 15708  5899 pts/0    15708 S+    1002   0:00 ./mytest8631 16126 16125  8631 pts/1    16125 S+    1002   0:00 grep --color=auto5899
[HJM@hjmlcc ~]$ 

bash 进程和 init 进程:
    bash 进程就是我们每打开一个终端后运行的第一个程序,他会捕捉你的键盘输入,看你输入了什么指令,则会解析执行对应的指令程序,在终端中运行的执行程序所对应进程默认父进程就是这个 bash 进程( 因为这些指令程序对应的进程都是这个 bash 进程创建的 )
    init 进程( 也叫1号进程,就是操作系统 )是系统内非常 重要的一个管理进程,系统中只有一个这个进程( bash 进程是打开了多少终端就会运行多少个 ),进程 PID 为1、


3.7、通过系统调用接口创建子进程 - fork 初识

    创建(启动)进程有很多方法,除了我们知道的运行可执行程序从而创建(启动)一个进程之外,还可以使用 Linux 操作系统所提供的系统调用接口 fork 直接创建(启动)某一个进程的子进程、        

[HJM@hjmlcc ~]$ man 2 fork//如果成功创建(启动)了当前进程的子进程,则会把当前进程的子进程的PID的值返回给当前进程(父进程)
//的id变量中,把0返回给当前进程的子进程的id变量中,因此,此时的Linux操作系统所提供的系统调用接
//口fork有两个返回值、//这里是查询Linux操作系统提供的系统调用接口,在本质上,fork也是一个函数,如上,他有两个返回值,在
//之前我们都没有遇到过、FORK(2)                 Linux Programmer's Manual                 FORK(2)NAMEfork - create a child processSYNOPSIS#include <unistd.h>pid_t fork(void); DESCRIPTIONfork()  creates  a new process by duplicating the calling process.The new process, referred to as the child, is an  exact  duplicateof  the calling process, referred to as the parent, except for thefollowing points:*  The child has its own unique process ID, and this PID does  notmatch the ID of any existing process group (setpgid(2)).*  The  child's  parent  process  ID  is  the same as the parent'sprocess ID.*  The child does not inherit its parent's memory locks (mlock(2),mlockall(2)).*  Process resource utilizations (getrusage(2)) and CPU time coun‐ters (times(2)) are reset to zero in the child.*  The child's set of pending signals is initially empty (sigpend‐ing(2)).*  The  child does not inherit semaphore adjustments from its par‐ent (semop(2)).*  The child  does  not  inherit  record  locks  from  its  parent(fcntl(2)).Manual page fork(2) line 1 (press h for help or q to quit)/return val
RETURN VALUEOn success, the PID of the child process is returned in  the  par‐ent,  and  0 is returned in the child.  On failure, -1 is returnedin the parent, no child process  is  created,  and  errno  is  setappropriately.//如果成功创建(启动)了当前进程的子进程,则会把当前进程的子进程的PID的值返回给当前进程(父进程)
//的id变量中,把0返回给当前进程的子进程的id变量中,如果没有成功,则会把-1返回给当前进程(父进程)
//的id变量中,此时并没有成功创建(启动)当前进程的子进程、ERRORSEAGAIN fork()  cannot  allocate sufficient memory to copy the par‐ent's page tables and allocate a  task  structure  for  thechild.EAGAIN It  was  not  possible  to create a new process because thecaller's RLIMIT_NPROC resource limit was  encountered.   Toexceed  this  limit,  the  process  must  have  either  theCAP_SYS_ADMIN or the CAP_SYS_RESOURCE capability.ENOMEM fork() failed to allocate the necessary  kernel  structuresbecause memory is tight.ENOSYS fork()  is  not  supported  on  this platform (for example,hardware without a Memory-Management Unit).CONFORMING TOSVr4, 4.3BSD, POSIX.1-2001.NOTESUnder Linux, fork() is implemented using copy-on-write  pages,  sothe only penalty that it incurs is the time and memory required toduplicate the parent's page tables, and to create  a  unique  taskstructure for the child.Since version 2.3.3, rather than invoking the kernel's fork() sys‐tem call, the glibc fork() wrapper that is provided as part of theNPTL  threading  implementation  invokes  clone(2) with flags thatprovide the same effect as the traditional system call.   (A  callto  fork() is equivalent to a call to clone(2) specifying flags asManual page fork(2) line 101/154 89% (press h for help or q to quit)q
[HJM@hjmlcc ~]$ ls
Makefile  mytest.c
[HJM@hjmlcc ~]$ cat mytest.c
#include<stdio.h>
#include<unistd.h>
int main()
{pid_t id = fork();printf("hello,lcc\n");sleep(1);return 0;
}
[HJM@hjmlcc ~]$ make
gcc mytest.c -o mytest
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ./mytest
hello,lcc
hello,lcc
[HJM@hjmlcc ~]$   //打印了两次、
//这是因为:父进程和子进程共享且都会执行Linux操作系统所提供的系统调用接口fork调用处之后的所有
//代码和该系统调用接口 fork 函数体内部的所有的代码、//例子:
[HJM@hjmlcc ~]$ ls
lcc.c  Makefile  mytest.c
[HJM@hjmlcc ~]$ cat lcc.c
#include<stdio.h>
#include<unistd.h>
int main()
{printf("321\n");pid_t id = fork();printf("123\n");return 0;
}
[HJM@hjmlcc ~]$ gcc lcc.c
[HJM@hjmlcc ~]$ ls
a.out  lcc.c  Makefile  mytest.c
[HJM@hjmlcc ~]$ ./a.out
321
123
123
[HJM@hjmlcc ~]$ 
[HJM@hjmlcc ~]$ ls
Makefile  mytest.c
[HJM@hjmlcc ~]$ cat mytest.c
#include<stdio.h>
#include<unistd.h>
int main()
{pid_t id = fork();printf("hello,lcc!id:%d\n",id);sleep(1);return 0;
}
[HJM@hjmlcc ~]$ ls
Makefile  mytest.c
[HJM@hjmlcc ~]$ make
gcc mytest.c -o mytest
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ./mytest
hello,lcc!id:23465
hello,lcc!id:0
[HJM@hjmlcc ~]$ ./mytest
hello,lcc!id:23812
hello,lcc!id:0
[HJM@hjmlcc ~]$ ./mytest
hello,lcc!id:23832
hello,lcc!id:0
[HJM@hjmlcc ~]$ //上述现象在讲解进程地址空间时再进行阐述、//新建会话0:
[HJM@hjmlcc ~]$ ls
Makefile  mytest.c
[HJM@hjmlcc ~]$ cat mytest.c
#include<stdio.h>
#include<unistd.h>
int main()
{pid_t id = fork();if(id == 0){//当前进程(父进程)的子进程、while(1){printf("我是子进程!,我的进程ID(PID)是:%d,我的父进程ID(PPID)是:%d\n",getpisleep(1);}}else{//当前进程(父进程)、while(1){printf("我是父进程!,我的进程ID(PID)是:%d,我的父进程ID(PPID)是:%d\n",getpisleep(1);}}return 0;
}
//在C语言中,if和else不可以同时执行,且在C语言中没有可能同时存在两个或两个以上的死循环、
[HJM@hjmlcc ~]$ make
gcc mytest.c -o mytest
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ./mytest
我是父进程!,我的进程ID(PID)是:19571,我的父进程ID(PPID)是:5899
我是子进程!,我的进程ID(PID)是:19572,我的父进程ID(PPID)是:19571
我是父进程!,我的进程ID(PID)是:19571,我的父进程ID(PPID)是:5899
我是子进程!,我的进程ID(PID)是:19572,我的父进程ID(PPID)是:19571
我是父进程!,我的进程ID(PID)是:19571,我的父进程ID(PPID)是:5899
我是子进程!,我的进程ID(PID)是:19572,我的父进程ID(PPID)是:19571
我是子进程!,我的进程ID(PID)是:19572,我的父进程ID(PPID)是:19571
我是父进程!,我的进程ID(PID)是:19571,我的父进程ID(PPID)是:5899
我是子进程!,我的进程ID(PID)是:19572,我的父进程ID(PPID)是:19571
我是父进程!,我的进程ID(PID)是:19571,我的父进程ID(PPID)是:5899
我是子进程!,我的进程ID(PID)是:19572,我的父进程ID(PPID)是:19571
...
...//新建会话1:
[HJM@hjmlcc ~]$ ls
Makefile  mytest  mytest.c
[HJM@hjmlcc ~]$ ps ajx | head -1 && ps ajx | grep 'mytest' | grep -v grepPPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND5899 19571 19571  5899 pts/0    19571 S+    1002   0:00 ./mytest
19571 19572 19571  5899 pts/0    19571 S+    1002   0:00 ./mytest
[HJM@hjmlcc ~]$ //1、
//这是因为:父进程和子进程共享且都会执行Linux操作系统所提供的系统调用接口fork调用处之后的所有
//代码和该系统调用接口 fork 函数体内部的所有的代码、//2、
//父进程和子进程各自的id变量中的值不同,在调用Linux操作系统所提供的系统调用接口fork之后,可以
//通过父进程和子进程中各自不同的id变量中的值进行判断,让父进程和子进程分别执行不同的代码块、

补充一:

    在 Linux 操作系统所提供的系统调用接口 fork 中,当成功创建(启动)某一个进程的子进程时,为什么会把当前进程的子进程的 PID 的值返回给当前进程(父进程)的 id 变量中,把 0 返回给当前进程的子进程的 id 变量中呢?

    创建(启动)某一个进程的子进程本质上就是相当于在操作系统中多一个执行流来帮助我们完成一部分代码,这就叫做多进程代码,父进程比子进程一定是1 :n( n>=1,能够称其为父进程,则它至少有一个子进程 ),但是任意一个子进程有且仅有一个父进程,因此,父进程必须要有标识子进程的方案,这个方案就是当成功创建(启动)某一个进程的子进程时,把当前进程的子进程的 PID 的值返回给当前进程(父进程)的 id 变量中,而把 0 返回给当前进程的子进程的 id 变量中是因为,子进程最重要的是要知道自己被创建成功了,任意一个子进程有且仅有一个父进程,因此子进程寻找父进程的成本非常低,只需要使用 Linux 操作系统所提供的系统调用接口 getppid 即可,所以,只需要把 0 返回给当前进程的子进程的 id 变量中即可、


补充二:

    在 Linux 操作系统所提供的系统调用接口 fork 的函数体中,当成功创建(启动)某一个进程的子进程时,为什么会进行两次返回操作 ?

    子进程所有的属性数据信息,大部分(基本上,比如优先级,状态等等,具体有哪些会在后期再进行具体的阐述)都是从该子进程的父进程继承(拷贝)得到的,但并不都是从该子进程的父进程继承(拷贝)得到的,比如:该子进程的进程 ID(PID) 等,就不是从该子进程的父进程继承(拷贝)得到的、

    子进程被创建(启动)出来就是为了执行代码,计算数据的,那么该子进程的代码从哪里来的呢 ?,答:没有地方来,子进程只能与其父进程执行一样的代码,我们所谓的:父进程和子进程共享且都会执行Linux操作系统所提供的系统调用接口 fork 调用处之后的所有的代码和该系统调用接口 fork 函数体内部的所有的代码,在此,本质上,子进程共享并执行 Linux 操作系统所提供的系统调用接口 fork 调用处之后的所有的代码和该系统调用接口 fork 函数体内部的所有的代码都是属于其父进程的代码,注意:父进程与子进程两者的数据(全局变量,静态变量等等数据)要各自独立开来,因为进程具有独立性,父子进程的数据必须是独立分开的,在后期讲解写时拷贝时再进行具体阐述,虽然父进程和子进程共享且都会执行Linux操作系统所提供的系统调用接口 fork 调用处之后的所有代码和该系统调用接口 fork 函数体内部的所有的代码,但是常规情况下,可以通过父进程和子进程各自的 id 变量中的值不同,在调用 Linux 操作系统所提供的系统调用接口 fork 之后,可以通过父进程和子进程中各自不同的 id 变量中的值进行判断,让父进程和子进程分别执行不同的代码块、

    调用一个函数,当在这个函数的函数体中准备 return 时,此时该函数的主题,核心功能已经完成了,此处的 return ,并不是核心逻辑的一部分,这就意味着,当在 Linux 操作系统所提供的系统调用接口 fork 的函数体中,在执行 return 代码(语句)之前,其当前进程的子进程就已经被创建(启动)好了、

    如何理解进程被运行?,我们知道,进程等于加载到内存中的可执行程序(代码及数据)加上该进程对应的内核数据结构( 该进程对应的描述该进程所使用的 struct 结构体(task_struct) ),但是并不代表描述某一个进程所使用的 struct 结构体只能在一个双链表中,也可以同时放在其他的结构中,其次,在操作系统内部存在一个我们称为调度器的代码模块、

    在 Linux 内核中的每一个 CPU 中,都会存在一个叫做运行队列( runqueue )的东西,运行队列中所放的都是进程,所谓的调度器调度,就是让该运行队列中的每一个进程根据他们的优先级(使用队列就已经明确了优先级的问题)去被 CPU 运行,当某一个进程被调度,也就是被 CPU 运行时,本质上就是让 CPU 找到该进程对应的可执行程序(代码和数据),通过找到的代码去访问它的数据,这样就是运行了该进程,还要注意,我们所谓的创建(启动)某一个进程的子进程,该子进程还需要被 CPU 运行,还需要把该子进程放到运行队列中,以此供 CPU去调度,该子进程的可执行程序(代码和数据,此处所谓的数据是该子进程独立的数据,而此处所谓的代码指的就是该子进程的父进程的代码),由上述可知,在 Linux 操作系统所提供的系统调用接口 fork 的函数体中,当在执行 return 代码(语句)之前,其当前进程的子进程就已经被创建(启动)好了,即:在 Linux 操作系统所提供的系统调用接口 fork 的函数体中,在执行 return 代码(语句)之前,就已经存在了父进程和子进程,并且此时,父进程和子进程都已经放在了运行队列中,父进程和子进程都有可能随时被 CPU 调度,当两者都被 CPU 调度时,父进程和子进程共享且都会执行 Linux 操作系统所提供的系统调用接口 fork 调用处之后的所有代码和该系统调用接口 fork 函数体内部的所有的代码,所以此处就都会执行 Linux 操作系统所提供的系统调用接口 fork 的函数体中的 return代码(程序),因此,在 Linux 操作系统所提供的系统调用接口 fork 的函数体中进行两次返回操作,且有对应的两个返回值、

拓展:

    我们在写 C 代码时所使用的变量,有可能并不是存在于内存中,实际上,这一个变量名最后会对应到不同的存储空间中,在讲解地址空间时再进行具体的阐述、

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于51单片机的简易数字计算器Proteus仿真

资料编号&#xff1a;115 下面是相关功能视频演示&#xff1a; 115-基于51单片机的简易数字计算器Proteus仿真&#xff08;源码仿真全套资料&#xff09;功能说明&#xff1a; 该计算器系统51 系列的单片机进行的数字计算器系统设计&#xff0c;可以完成计算器的键盘输入&…

一看就会的Java方法

文章目录一、方法的定义和使用&#x1f351;1、为什么引入方法&#xff1f;&#x1f351;2、方法的定义&#x1f351;3、方法调用的执行过程&#x1f351;4、实参和形参的关系二、方法重载&#x1f351;1、为什么需要方法重载&#x1f351;2、方法重载的概念和特点&#x1f351…

用DIV+CSS技术设计的体育主题网站(足球介绍)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

【面经】之小鼠喝药问题

题目 现在有 10 只小白鼠和 1000 支药水&#xff0c;1000 支药水中有且仅有一支药水有毒&#xff0c;如果小白鼠喝下毒药&#xff0c;那么毒发的时间是两小时。 现在只给你两小时的时间&#xff0c;请问如何用这 10 只小白鼠测出哪支药水有毒&#xff1f;&#xff08;忽略小白…

linux系统文件权限

目录 shell命令以及运行原理 具体体现(命令行解释器) Linux权限的概念 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户 su指令 Linux权限管理方面 文件访问者的分类&#xff08;人&#xff09; 为什么要有所属组&#xff1f; 文件属性…

STM32 Bootloader开发记录 2

在《stm32 bootloader开发记录.md》文档中&#xff0c;已经实现了Bootloader下的升级功能。可以在Bootloader启动时&#xff0c;进入升级模式&#xff0c;使用串口传输数据&#xff0c;来下载固件到flash中。 但是&#xff0c;在实际应用中&#xff0c;一般是在应用运行过程中…

基于单片机的指纹门禁设计

功能&#xff1a; 研究内容&#xff1a;本课题以单片机为核心采用C语言来开发一指纹电子密码锁。系统拟在Altium Designer9开发平台上设计原理图&#xff0c;并绘制PCB并制成单片机开发板&#xff0c;然后根据原理图将相关元器件焊接到开发板上。软件部分在Keil uVision4开发…

餐饮美食网页设计(HTML+CSS+JavaScript)

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

目标检测算法——自动驾驶开源数据集汇总2(附下载链接)

>>>深度学习Tricks&#xff0c;第一时间送达<<< 目录 一、Highway Driving 二、Mapillary Vistas 三、Cityscapes 四、CamVid >>>一起交流&#xff01;互相学习&#xff01;共同进步&#xff01;<<< 近期&#xff0c;小海带在空闲之余…

【FPGA】FPGA实现IIC协议读写EEPROM(二) -----EEPROM读写控制模块实现

EEPROM读写控制模块实现一、模块功能分析二、输入/输出信号三、EEPROM读写控制模块状态机四、EEPROM读写控制模块实现五、仿真测试写在前面&#xff1a; FPGA实现IIC协议读写EEPROM相关文章&#xff1a; IIC通信协议 【FPGA】FPGA实现IIC协议读写EEPROM&#xff08;一&#xff…

Kafka消费者之相关参数及分区分配再平衡

一、消费者重要参数 深刻的理解这些参数有利于大家在面对自己的项目场景上对配置文件有更好的把握&#xff01; 参数名称描述bootstrap.servers向 Kafka 集群建立初始连接用到的 host/port 列表。key.deserializer 和value.deserializer指定接收消息的 key 和 value 的反序列…

Spring--基于注解管理bean

基于注解管理bean 实验一&#xff1a;标记与扫描 注解 和 XML 配置文件一样&#xff0c;注解本身并不能执行&#xff0c;注解本身仅仅只是做一个标记&#xff0c;具体的功能是框架检测到注解标记 的位置&#xff0c;然后针对这个位置按照注解标记的功能来执行具体操作。 本质…

【ASM】字节码操作 工具类与常用类 asm-utils 与 asm-commons

1.概述 本章节主要是对 ASM中的 工具类与常用类 ,包asm-utils 与 asm-commons 两个包中的一些类进行讲解的介绍。 2. asm-util 在asm-util.jar当中,主要介绍CheckClassAdapter和TraceClassVisitor类。在TraceClassVisitor类当中,会涉及到Printer、ASMifier 和Textifier类。…

Vue中 引入使用 element-resize-detector 监听 Dom 元素 宽度、高度 变化

1. 前言 很多做pc端平台的小伙伴都遇到过这样一个问题&#xff1a;在做侧边栏菜单时会有一个收缩和展开的一个功能&#xff0c;在伸缩的过程中右边的页面的宽度就会随之改变。我上网查了查 &#xff0c;也动手试了试 window.onresize ()>{}。却不尽人意&#xff0c;因为它…

进程管理命令 动态监控进程 rpm yum

学习视频:074_韩顺平Linux_服务管理(2)_哔哩哔哩_bilibili 目录 进程管理命令基本介绍 PS命令 显示系统执行的进程 终止进程kill和killall 查看进程树pstree 服务管理 服务管理 打开或者关闭指定端口 动态监控进程 监控网络状态 …

数字IC手撕代码-XX公司笔试真题(脉冲密度调制)

前言&#xff1a; 本专栏旨在记录高频笔面试手撕代码题&#xff0c;以备数字前端秋招&#xff0c;本专栏所有文章提供原理分析、代码及波形&#xff0c;所有代码均经过本人验证。 目录如下&#xff1a; 1.数字IC手撕代码-分频器&#xff08;任意偶数分频&#xff09; 2.数字I…

nginx之https加密网站

目录 一、密钥算法 二、SSL虚拟主机 一、密钥算法 常见密钥算法&#xff1a; 对称加密&#xff1a;AES、DES 非对称加密&#xff1a;RSA、DSA 【注】对称加密的加密和解密使用的是同一把钥匙&#xff0c;非对称加密的加密和解密使用的不是一把钥匙&#xff0c;在对网…

0093 二分查找算法,分治算法

/* * 二分查找算法 * 前提&#xff1a;数组必须有序 * 1.确定该数组的中间值下标 mid(leftright)/2 * 2.让需要查找的数target和arr[mid]比较 * * 非递归算法 * 递归算法 */ public class BinarySearch_ { public static void main(String[] args) { int[…

【Python】常量和变量类型

目录 1.常量和表达式 2. 变量和类型 2.1 变量是什么 2.2 变量的语法 2.3 变量的类型 2.4 动态类型特性 1.常量和表达式 我们可以把Python当成一个计算器&#xff0c;来进行一些算式运算&#xff0c;如 print(1 2 - 1) print(1 2 * 2) print(1 2 / 2) 注&#xff1a;在…

pta-sql补题(2)

目录​​​​​​​ 插入insert&#xff1a; 两种语法形式&#xff1a; 插入记录&#xff08;一&#xff09; 表结构: 表样例 输出 插入记录&#xff08;二&#xff09; 表结构: 表样例 结果判定: 更新update 语法 更新记录&#xff08;一&#xff09; 表结构: …