尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Linux应用层开发 --- 进程

Linux应用层开发 --- 进程 多任务让程序具备同时处理多个任务的能力并发如何实现多任务多进程、多线程1.什么是进程进程正在执行的程序需要消耗内存和CPU进程和程序的区别1程序是一组数据指令集和存储在硬盘空间是静态的2进程存储在内存空间执行过程需要CPU参与内存CPU3进程具备动态生命周期从启动到消亡4程序运行起来产生一个进程也可产生多个进程5在一个进程中也可以执行多个程序2.进程的创建./a.out ----- 启动进程进程在被创建的时候操作系统会为该进程分配0-4G的虚拟内存空间进程是操作系统资源分配的最小单位3.进程的调度CPU调度进程宏观并行、微观串行并发并行多个任务同时执行CPU调度算法1时间片轮询算法2先来先服务、后来后服务算法3高优先级优先执行算法4短作业优先算法4.进程的状态操作系统进程状态三态图Linux操作系统进程状态及转换关系1运行态用户运行态、内核运行态 R正在执行且被CPU任务调度所执行的进程2就绪态 R正在执行、没有CPU任务调度执行的进程只缺少CPU3可唤醒等待态 S也称为睡眠态、阻塞等待资源的进程4不可唤醒等待态 D不想被CPU任务调度所打断的进程任务可以设置不可唤醒等待态5暂停态 T被暂停执行的进程6僵尸态 Z进程执行结束空间没有被回收7结束态 X进程执行结束空间被回收S处于可中断睡眠状态的前台进程S处于可中断睡眠状态的后台进程T处于暂停态的后台进程与终端相关联的多为前台进程5.进程的消亡1进程退出进程执行结束退出主函数中遇到return退出exit() 、_exit() 、Exit()结束进程#include stdlib.hvoid exit(int status);功能退出一个进程参数status进程结束时的状态0正常退出0因为其他原因退出#include unistd.hvoid _exit(int status);#include stdlib.hvoid _Exit(int status);通过信号结束一个进程kill -9 进程ID2进程回收僵尸进程和孤儿进程僵尸进程进程已退出但其资源空间没有被其父进程回收如何避免僵尸进程产生1由其父进程对僵尸态进程进行回收wait()、waitpid()2让进程成为一个孤儿进程结束后由操作系统回收孤儿进程父进程先结束其父进程创建的子进程成为孤儿进程将会被系统进程所收养结束后由系统进程回收。比j如守护进程6.进程相关命令1ps -aux查看操作系统所有进程的相关参数PID进程ID、创建者、状态、CPU占有率、内存占有率等ps -aux | grep ./a.out利用管道符查找某指定名称的进程| 管道将前面的输出作为后面的输入grep字符串查找2ps -ef查看操作系统所有进程的相关参数PID、PPID父进程创建新进程的进程是该新进程的父进程PPID父进程ID号子进程创建出来的新进程是子进程PIDProcess ID 进程ID号3top动态查看进程的状态及CPU占有率、内存占有率4pstree以树状形式查看进程间的创建关系族谱图pstree -sp以树状形式查看带ID号pstree -sp 进程ID查看指定ID的进程的创建关系5killkill -信号名称/信号ID PID给PID对应的进程发送一个信号kill -l查看系统定义出来的信号kill -9 进程ID结束一个进程杀死进程常用9杀死进程 18继续 19暂停6jobs查看当前后台进程编号7fg 后台进程编号将一个后台进程调到前台7.进程相关的函数fork()子进程操作系统通过完整拷贝父进程0-3G的用户空间数据到子进程内核空间拷贝部分内容PCB块PID不拷贝、PPID不拷贝程序执行的位置、文件管理要拷贝PCB块进程控制块注意1进程共用3G-4G这1G的内核空间2但各自进程0-3G用户空间互相独立不能互相通信3进程间不能直接通信通信需要借助内核空间IPC机制#include sys/types.h#include unistd.hpid_t fork(void);功能创建新进程新进程叫子进程原来的进程为父进程返回值成功父进程中返回子进程的PID号子进程中返回0失败-1没有新进程被创建getpid()获取当前进程自己的PID号petppid()获取当前进程的父进程的PID号示例#include stdio.h #include sys/types.h #include unistd.h int main(void) { pid_t pid fork(); printf(pid %d\n,pid); if(pid 0) { while(1) { printf(Father process:myid %d, son id %d\n,getpid(),pid); sleep(1); } } else if(pid 0) { while(1) { printf(son process:myid %d, father id %d\n,getpid(),getppid()); sleep(1); } } else { perror(fork error); } return 0; }wait()#include sys/types.h#include sys/wait.hpid_t wait(int *wstatus);功能阻塞回收僵尸态进程资源空间和状态参数wstate用来存储进程退出时的状态参数返回值成功返回回收到的子进程的ID失败-1wait(NULL);pid_t waitpid(pid_t pid, int *wstatus, int options);功能回收指定进程的资源和wait功能相似比wait更灵活参数pid-1回收指定进程组内的任意子进程-100等待GID100的进程组中的任意子进程-1 回收任意子进程组内外0 回收和当前调用waitpid一个组的所有子进程组内0 回收指定ID的子进程status子进程退出时候的状态如果不关注退出状态用NULLoptions0表示回收过程会阻塞等待WNOHANG表示非阻塞模式回收资源返回值成功返回接收资源的子进程pid失败-1设定为非阻塞且没有回收到的子进程返回0waitpid如果以阻塞方式回收和wait使用方式一样如果父进程有任务需要执行则可以选择waitpid非阻塞方式回收此时搭配轮询方式实现。8.exec函数簇作用在一个进程中执行外部的一个可执行程序本质exec将要执行的外部程序替换到了进程的文本区#include unistd.hextern char **environ;int execl(const char *path, const char *arg, .../* (char *) NULL */);参数path可执行程序所在路径例如/bin/lsarg执行可执行程序时传递的参数NULL参数的结束标志表示参数传递完毕返回值成功不返回失败-1int execlp(const char *file, const char *arg, .../* (char *) NULL */);功能执行PATH环境变量保存的路径中的可执行程序参数file可执行文件的名称arg执行可执行程序时传递的参数NULL参数的结束标志表示参数传递完毕int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);参数path可执行程序所在路径argv存放可执行程序时传递参数的容器指针数组file可执行文件的名称l list---列表lppath环境变量保存了系统中已有的可执行程序的存放路径v vector容器注exec不会产生新进程只做文本区的代码替换#include stdlib.h int system(const char *command); 有新进程产生新进程执行完后会继续向下执行 等同于 #include stdio.h #include unistd.h #include sys/types.h #include sys/wait.h #include stdlib.h #include string.h void mysystem(char *cmd) { char* argv[10] {NULL}; int i 0; char tmp[128] {0}; strcpy(tmp,cmd); argv[i] strtok(tmp, ); while(argv[i] ! NULL) { i; argv[i] strtok(NULL, ); } for(int j0; ji; j) { printf(argv[%d] %s\n,j,argv[j]); } pid_t pid fork(); if(pid 0) { wait(NULL); } else if(0 pid) { execvp(argv[0],argv); } else { perror(fork error); } } int main(void) { printf(before system pid %d\n, getpid()); mysystem(ls -l); printf(after system\n); return 0; }
返回列表