进程和程序的区别:
程序是一段静态·的代码,是保存在非易失储存器上的制令和数据的有序集合,没有任何执行的概念;而进程是一个动态的概念,它是程序的一次执行过程,包括了动态创建、调度、执行和消亡的整个过程,他是程序执行和资源管理的最小单位。可以用一个程序创建许多进程。或者反过来说,许多进程运行的可以是同一程序
fork函数,fork函数能复制整个父进程的所有代码,但不同的是其访问的实际物理地址和父进程不通,子进程虽然复制了父进程的所有代码,但实际执行的是fork()函数以下的部分,若当前进程是父进程则返回值大于零,否者返回值等于零
简单的fork函数伪代码:
#include <unistd.h>
pid_t fork(void) {
// 创建一个新的进程
// 复制父进程的内存空间,包括代码、数据、堆栈等,采用写时复制技术
if (/* 当前进程是子进程 */) {
return 0; // 返回0表示这是子进程
} else if (/* 当前进程是父进程 */) {
return child_pid; // 返回子进程的进程ID
} else {
return -1; // 表示fork失败
}
}
fork函数运用代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, const char *argv[]){
pid_t pid;
printf("我是父进程我正准备创建一个子进程\n");
pid = fork();//创建一个子进程
if(pid == -1){
printf("进程创建失败\n");
}
else if(pid > 0){
printf("我是父进程已经成功创建子进程编号为: %d\n", pid);
}
else if(pid == 0){
printf("我是子进程\n");
}
return 0;
}
getpid获取进程自身ID,getppid获取进程父进程的ID
检验地址使用关系代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, const char *argv[]){
int cnt = 0;
pid_t pid;
printf("我是父进程我正准备创建一个子进程\n");
pid = fork();//创建一个子进程
if(pid == -1){
printf("进程创建失败\n");
}
else if(pid > 0){
cnt = cnt + 1;
printf("我是父进程已经成功创建子进程编号为: %d\n", pid);
printf("CNT: %d,address: %p\n", cnt , &cnt);
}
else if(pid == 0){
cnt = cnt + 1;
printf("我是子进程我的编号为%d,我的父进程编号%d\n", getpid(), getppid());
printf("CNT: %d,address: %p\n", cnt , &cnt);
}
return 0;
}
可以看出父子进程,输出cnt的地址都是一样的,说明父子进程都用的一个虚拟地址,但是cnt输出却都是1说明两者cnt的物理地址不一样