一、进程
1.进程是程序运行的过程,包括进程的创建,进程的调度,进程的消亡
2.程序是在磁盘空间中存放的一段数据的集合
3.进程命令:
①top:根据CPU占用率查看进程信息
②ps -ef:可以查看一个进程的父进程ID号
③ps -aux:可以看到进程的状态
④pstree:查看进程关系
⑤kill:可以用来杀死进程
⑥ps -ef | grep 字符串:在ps -ef生成的信息中找字符串相关联的若干行
⑦./a.out &:让a.out在后台运行;jobs:查看后台运行的任务;fg 标号:标号对应的后台任务放到前台执行。
4.精灵进程/守护进程:随着操作系统开启运行程序,随着操作系统结束,进程结束,为用户提供服务
5.进程的创建:在32为操作系统中,进程创建时,操作系统分配0-4g虚拟内存空间,分为:文本段、数据段、系统数据段,常用fork()函数创建,函数原型为:pid_t fork(void),成功在父进程中返回创建的子进程的PID,在子进程中返回0,失败返回-1.
6.获取调用函数进程的ID号:pid_t getpid(void)
7.多进程创建的特点:不管几个进程都是占0-4g虚拟内存空间,并且进程空间之间都是独立的
8.进程调度的特点:宏观并行,微观串行。宏观并行就是从用户角度出发,多个任务在同时向下执行;微观串行则是从CPU角度出发,在多个任务中来回切换调度任务实现多个任务的执行
9.常见的进程调度算法:先来先来先执行,后来后执行的调度算法;高优先级调度算法;时间片轮转调度算法;多级队列反馈调度算法;负载均衡调度算法
10.进程的状态:就绪态、运行态(R);睡眠态(可唤醒等待态 S);不可唤醒等待态(D);暂停态(T);僵尸态(Z);结束态(X)
11.进程的消亡:僵尸态:进程代码执行结束,但是空间没有被回收。子进程结束,父进程没有回收子进程空间,子进程就会成为僵尸进程。为了避免僵尸进程,就得先让父进程结束,子进程成为孤儿进程,然后子进程结束,被系统进程(init进程)回收进程空间。或者子进程结束,父进程回收子进程空间,避免产生僵尸进程。
12.exit函数:void exit(int status);让进程空间结束。void _exit(int status);让进程立即结束。
13.wait函数:pid_T wait(int *wstatus);回收子进程空间,成功返回回收到的子进程PID,失败返回-1。wait具有阻塞功能,只有一个子进程时,阻塞等待直到子进程结束才会继续向下执行,如果没有子进程,返回-1,有多个子进程,wait回收先结束的子进程;wait可以实现同步的功能。
WIFEXITED:子进程是否正常退出
WEXITSTATUS:获得子进程退出时的值
WIFSIGNALED:子进程是否被信号杀死
WTERMSIG:获得杀死子进程的编号
代码:
二、线程
1.线程是一个轻量级的进程,包括创建、调度和回收的整个过程,线程被创建后,独享栈区,共享进程中的文本段、数据段和堆区。
2.线程是独享8M栈区空间,其余进程中文本段、数据段、堆区及其余线程共享,其他和进程基本上一样。
3.线程和进程的区别:进程是系统资源分配的最小单元,而线程是CPU任务调度的最小单元
4.多线程执行效率大于多进程:因为多线程位于一个进程空间内部,调度任务时不需要切换进程空间,而多进程空间是独立的,任务调度CPU时要在不同的进程空间切换,增大系统的资源开销
5.多线程通信效率大于多进程:这是因为多线程位于同一个进程空间内部,除了栈区其他都是共享的,而多进程空间独立,没有共享空间,多进程间通信需要依赖第三方的文件才能实现通信
6.多进程的安全性大于多线程:这是因为多线程除了栈区其他都是共享的,一个线程异常就会结束,而多进程空间是独立的,一个进程异常不影响其他进程。
7.多进程的复杂度大于多线程:这是因为多线程操作共享空间会引发资源竞争,需要使用互斥锁来解决资源竞争,而多进程空间独立,没有共享空间,不会引发资源竞争,不需要考虑加锁。
三、互斥锁
1.pthread_mutex_t lock;
2.pthread_mutex_init(&lock, NULL);
3.加锁:pthread_mutex_lock(&lock);
4.解锁:pthread_mutex_unlock(&lock);
5.pthread_mutex_destroy(&lock);
四、死锁
1.多进程间通信由于加锁问题导致多任务均无法向下执行的状态称为死锁。
2.死锁产生的四个必要条件:
①互斥条件
②不可剥夺条件
③请求保持
④循环等待
3.避免死锁产生:
①多个线程任务加锁顺序保持一致
②pthread_mutex_trylock 替换 pthread_mutex_lock