一、什么是进程
(一)进程的含义?
进程是一个程序执行的过程,会去分配内存资源,cpu的调度
(二)进程分类:
1、交互式进程
2、批处理进程 shell脚本
3、 守护进程
(三)进程与程序的区别
1)程序是永存,进程是暂时的
2)进程有程序状态的变化,程序没有
3)进程可以并发,程序无并发
4)进程与进程会存在竞争计算机的资源
5)一个程序可以运行多次,变成多个进程
一个进程可以运行一个或多个程序
(四)进程的作用:
并发并行(各执行各的)
(五)进程的状态:
3个状态,就绪→执行态→阻塞(等待,睡眠)基本操作系统
linux中的状态,运行态,睡眠态,僵尸态,暂停态。
(1)运行态(running):进程占有处理器正在运行。
(2)就绪态(ready):进程具备运行条件,等待系统分配处理器以便运行。
(3)阻塞态(blocked):又称为或睡眠(sleep)态,指进程不具备运行条件,正在等待某个事件的完成。
(4)僵尸态(zombie):子运行完,父没运行完,子进程会以终止状态保持在进程表中,并且会一直在等待父进程读取才能退出。
(5)孤儿态:父运行完,子没运行完,子处于托管状态,加重系统负担
(6)创建态:进程正在被创建,但尚未转到就绪态。
(7)终止态:进程已经完成执行并准备被撤销。
进程的状态:PROCESS STATE CODESHere are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a process:D uninterruptible sleep (usually IO) //不可中断的睡眠态R running or runnable (on run queue) // 运行态S interruptible sleep (waiting for an event to complete)//可中断的睡眠态T stopped by job control signal // 暂停态t stopped by debugger during the tracingW paging (not valid since the 2.6.xx kernel)X dead (should never be seen)Z defunct ("zombie") process, terminated but not reaped by its parentFor BSD formats and when the stat keyword is used, additional characters may be displayed:< high-priority (not nice to other users)N low-priority (nice to other users)L has pages locked into memory (for real-time and custom IO)s is a session leaderl is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)+ is in the foreground process groupR --- 运行态 D --- 不可中断 睡眠态S --- 可中断 睡眠态 T --- 暂停态 Z --- 僵尸态
cb
struct task_struct {PID, //进程标识符PPID, //父进程ID号 parent 当前工作路径 //chdirumask //0002进程打开的文件列表 //文件IO中有提到信号相关设置 //处理异步io, ---段错误用户id,组id进程资源的上限
}
二、进程管理的命令
1、top //类似Windows的下任务管理器
2、ps -eLf | head -1 //可以观察到 PID PPID
3、ps -eLf | grep a.out //查看a.out 信息 //可以观察到 PID PPID
4、ps -aux | grep a.out //可以查看进程 的状态
5、pstree //进程树
6、pstree -sp pid号 //查看指定的进程的关系
7、kill //给进程发信号 //kill -l //查看可以发送的信号
操作:
将子进程杀死 。结束子进程,父进程还在,但是父进程并没有对子进程"收尸"
操作:
将父进程杀死 。子进程 还在 ,父进程不在 ---- 孤儿进程
---- 此时由init进程 收养
特殊:
孤儿进程
子进程 还在,父进程不在
僵尸进程
子进程 结束,父进程还在,且父进程并未"收尸"
僵尸态进程有危害
三、函数
pid_t fork(void);
功能:
创建子进程 (通过复制调用进程)
参数:
void
返回值:
成功
在父进程中 返回子进程的pid号
在子进程中 返回0
失败
-1 && errno 被设置
pid号:
pid 本质上就是一个数值
正整数 1
#include<stdio.h>
#include<unistd.h>int main(int argc, const char *argv[])
{pid_t pid = fork();if(pid<0){perror("fork fail");return -1;}
while(1)
{if(pid > 0){printf("hello\n");}else if(pid ==0){printf("world\n");}
}return 0;
}
1、子进程先运行和是父进程先进程,顺序不确定。
变量不共享。
2、子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同。
3、此时,父子进程各自拥有独立的4g内存空间 (32位的系统)
4、功能
通过该函数可以从当前进程中克隆一个同名新进程。
克隆的进程称为子进程,原有的进程称为 父进程。
子进程是父进程的完全拷贝。
复制之后,
子进程和父进程 各自拥有自己的 用户空间(进程空间)
子进程和父进程的执行过程是从fork函数之后执行。
子进程与父进程具有相同的代码逻辑。
5、返回值:int 类型的数字。
在父进程中:成功 返回值是子进程的pid号 >0
失败 返回-1;
在子进程中:成功 返回值 0
失败 无
6、注意:
1.创建好之后,父子进程的运行顺序是不确定 ---全部取决于 操作系统的调度
注意:
1.父子进程创建好之后,各自拥有独立4G内存空间(32位系统)
2.他们的数据相互独立,父进程或子进程对数据的修改,不会相互影响,只会对各自造成影响
(一)、练习
如果两次fork同时前后执行,会生成几个进程?
fork();
fork();
他们之间的关系如何表示,
有多少个子进程,
有没有孙进程?
2、fork()&&fork()||fork(); //总共几个进程
#include<stdio.h>
#include<unistd.h>int main(int argc, const char *argv[])
{fork()&&fork()||fork();while(1);sleep(1); return 0;
}
3、练习:
自己分别定义一个 static的变量 static int a = 0;
全局变量 int b = 1;
堆区 int *p = (int *)malloc(sizeof(int));
*p = 2;
(做修改)父进程中 做加1的操作 ,
子进程中做加2的操作
sleep(1);
分别打印,查看效果!
#include<stdio.h>
#include<unistd.h>
#include <stdlib.h>int main(int argc, const char *argv[])
{pid_t pid = fork();static int a =0;int b = 1;int *p = (int *)malloc(sizeof(int));*p = 2;while(1){if(pid > 0){a++;b++;*p++;sleep(1);printf("father ");printf("a = %d b = %d *p = %d\n",a,b,*p);}else if(pid == 0){a+=2;b+=2;*p+=2;printf("sun ");printf("a = %d b = %d *p = %d\n",a,b,*p);sleep(1);}}return 0;
}
4、创建n个进程 :
输入n 创建n个子进程
#include<stdio.h>
#include<unistd.h>int main(int argc, const char *argv[])
{int n = 0;scanf("%d",&n);int i = 0;pid_t pid = 0;for(i = 0;i < n;i++){pid = fork();if(pid < 0){perror("fork fail");return -1;}if(pid>0){continue;}else if(pid == 0){break;}}while(1)sleep(1);return 0;
}