赞
踩
1.在操作系统上输入的指令。
2.已经启动的软件。
3.程序员在代码层面上调用系统调用创建进程。
linux中第一个创建的进程是init,操作系统以后的进程创建,就可以依靠该init进程为父进程创建子进程,创建的子进程也可以做为之后进程创建的父进程。所以进程的创建是依靠父进程创建出来的。在使用linux命令行解释器执行指令创建进程中,命令行解释器bash就是父进程。
top指令查看进程id
也可以ps axj | grep name查看某个名字的进程id
也可以使用系统调用getpid()获取当前运行进程的pid
ls /proc/id -l 查看进程当前目录等信息
每个进程都有自己的id编号pid,所以操作系统管理进程时,就可以找该进程对应的pid编号。
fork()是linux创建子进程的系统调用,返回值是整形,如果返回值为0,就是子进程,如果返回值大于0(父进程创建子进程的子进程pid),就是父进程,如果返回值小于0,创建子进程失败,返回值为-1,错误码被设置。
查看父进程可以调用getppid(),当程序被运行的时候,我们发现两个循环体尽然都有在执行,而且他们的进程pid都不一样,但是子进程的ppid和父进程的pid一样,说明子进程是由父进程创建的。这段代码看着好像只有一个执行流,但是有两个进程。他们在并行地运行,执行。进程的概念给上层用户提高了一个很好的假象,每个程序独自占用处理器的资源,独自占用一个内存资源。
#include <stdio.h> #include <unistd.h> #include <sys/types.h> int main() { int pid = fork(); printf("I am father process,my pid is: %d, my praent ppid is: %d#########\n", getpid(), getppid()); printf("I am running: pid :%d ppid:%d\n",getpid(),getppid()); if (pid == 0) { while (1) { printf("I am child process,my pid is: %d, my praent ppid is: %d\n", getpid(), getppid()); sleep(1); } } if (pid > 0) { while (1) { printf("I am father process,my pid is: %d, my Ppraent ppid is: %d\n", getpid(), getppid()); sleep(1); } } return 0; }
子进程创建的时候,是根据父进程为模板创建的,和父进程的代码和数据,内存共享的。创建的子进程连接到运行队列里。因为子进程是根据父进程为模板创建的,继承了父进程的代码和数据。可以看出在fork成功后,子进程也是可以看到fork之前的代码的。
父进程创建子进程后。代码和数据共享指向的内存空间也是一样的。如果有一个全局的变量,父子进程对这个进程操作不同。数据发送了改变,哪个进程先对这个数据改变,操作系统就会申请新的内存给该进程,这是为了保证进程的独立性,互补干扰,让进程有独自的存放空间。代码的全局变量num在不同的进程中,指向不同的指令,一个自增,一个自减,互补干扰。观察到对同一变量num取地址,发现一样,其实这个地址是虚拟地址,并不是真实的物理地址。父子进程对数据改变的话,真实物理地址就会不一样。
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <stdbool.h> static num = 100; int main() { int pid = fork(); printf("I am father process,my pid is: %d, my praent ppid is: %d#########\n", getpid(), getppid()); printf("I am running: pid :%d ppid:%d\n",getpid(),getppid()); if (pid == 0) { while (true) { printf("I am child process,my pid is: %d, my praent ppid is: %d\n", getpid(), getppid()); printf("num = %d,num address: %p\n",num++,&num); printf("#######################################\n"); sleep(1); } } if (pid > 0) { while (true) { printf("I am father process,my pid is: %d, my Ppraent ppid is: %d\n", getpid(), getppid()); printf("num = %d,num address: %p\n",num--,&num); printf("#######################################\n"); sleep(1); } } return 0; }
创建子进程本质上是为了和父进程执行不同的任务。所以创建子进程后,一般就会指向新重新加载到内存的代码和数据。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。