博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于进程的一些基础知识
阅读量:6935 次
发布时间:2019-06-27

本文共 2997 字,大约阅读时间需要 9 分钟。

  • 进程的概念

    程序

    > 存放在磁盘上的指令和数据的有序集合(文件);  > 静态的;复制代码

    进程

    > 执行一个程序所分配的资源的总称;  > 进程是程序的一次执行过程;  > 动态的,包括创建、调度、执行和消亡;复制代码
  • 进程的内容

    代码用户数据段系统数据段

    系统数据段包括了进程控制块、CPU寄存器的值、堆栈;

    进程控制块(pcb)

    > 进程标识PID;  >  进程用户的信息;  > 进程状态、优先级;  > 文件描述符表(记录了系统中打开的所有的文件的信息);复制代码

    CPU寄存器

    program counter (存放的是下一条指令的地址);

    保存了所有的局部变量;

  • 进程的类型

    交互进程

    在shell下启动。可以在前台运行,也可以是在后台运行;

    批处理进程

    和在终端无关,被提交到一个作业队列中,被作业管理工具顺序执行(开发时较少使用);

    守护进程

    和终端无关,一直在后台运行(生命期很长);

  • 进程状态

    运行态

    程序正在运行,或者准备运行;

    等待态

    程序在等待一个事件的发生或者某种系统资源(可中断和不可中断);

    停止态

    进程被终止,收到信号后可继续运行;

    死亡态

    已终止的进程,但pcb没有被释放;

  • 一些相关命令

    ps -ef显示当前时刻系统中所有进程的信息;ps -ef|grep <>筛选显示

    ps aux|grep <>-ef多显示进程的当前状态;

    top 查看进程的动态信息;

    /proc 进入该目录下查看进程的详细信息;

    nice -n <NI> ./<001> 按用户指定的优先级运行进程(默认的 nice 值是 0 ,区间为 -20 到 19),nice值越小,优先级越高;

    renice -n <NI> <PID> 改变正在运行进程的优先级;

    jobs 查看一个后台进程;

    fg <PID> 把一个后台进程放到前台;

    bg <PID> 让处于停止态的后台进程运行起来;

  • 创建子进程

  • fork函数

    头文件:

    #include <unistd.h>

    函数原型:

    pid_t fork(void);

    返回值:

    创建新的进程,失败时返回-1;

    fork()被调用一次会返回两次,成功时父进程返回子进程的进程号,子进程返回 0

    通过 fork 的返回值区分父进程和子进程;

    示例:

#include 
#include
#include
#include
int main(int argc,const char *argv[]){ pid_t pid; if ((pid = fork()) < 0) { perror("fork"); return -1; } else if (pid == 0) { printf("child process: my pid is %d\n",getpid()); } else{ printf("parent process: my pid is %d\n",getpid()); } return 0;}复制代码
  • 父子进程

    子进程继承了父进程的内容;

    父子进程有独立的地址空间,互不影响;

    若父进程先结束,子进程成为孤儿进程,会被init进程收养,同时变为后台进程;

    若子进程先结束,父进程没有及时回收,子进程则变为僵尸进程(pcb未被释放);

    父子进程的运行顺序不确定,取决于内核的调度;

  • 结束进程

  • exit / _exit函数

    头文件:

    #include <stdlib.h> #include <unistd.h>

    函数原型:

    void exit(int status);

    void _exit(int status);

    返回值;

    结束当前进程并将status返回;

    exit 结束进程时会刷新流的缓冲区;

    示例:

    #include 
    /*exit()的头文件*/#include
    /*_exit()的头文件*/#include
    int main(int argc,const char *argv[]){ printf("success"); /*换成_exit(0)则屏幕无输出*/ exit(0); printf("success too"); return 0;}复制代码
  • exec函数族

    进程的当前内容被替换,实现父子进程执行不同的程序;

  • execl / execlp 函数

    头文件: #include <unistd.h>

    函数原型:

    int execl(const char *path, const char *arg, ...);

    int execlp(const char *file, const char *arc, ...);

    path ,执行程序的名称和路径(绝对路径或相对路径);

    arg... 传递给执行程序的参数列表;

    file 执行的程序的名称,在PATH(shell的环境变量)中查找;

    返回值:

    成功执行指定的程序,失败则返回EOF;

    示例:(执行ls命令,显示/etc目录下所有的文件详细信息)

    if(execl("/bin/ls","ls","-a","-l","/etc",NULL) < 0) {   perror("exec error");}复制代码
    if(execlp("ls","-a","-l","/etc",NULL) < 0) {    perror("execlp error");}复制代码
  • execv / execvp 函数

    头文件:

    #include <unistd.h>

    函数原型:

    int execv(const char *path, char *const argv[]);

    int sescvp(const char *file, char *const argv[]);

    相较于execl()和execlp(),参数列表封装成字符指针数组;

    返回值:

    成功执行指定的程序,失败则返回EOF;

    示例:(功能同上)

    /*定义一个字符指针数组*/char *const buf[] = {
    "ls","-a","-l","/etc",NULL};if(execv("/bin/ls",buf) < 0) { perror("execv");}复制代码
  • system 函数

    属于比较简单的方法,不手动创建子进程;

    头文件:

    #incude <stdlib.h>

    函数原型:

    int system(const char *command);

    在当前进程中会自己创建子进程;

    返回值:

    成功时返回命令 command 的返回值,失败时返回EOF;

    当前进程等待 command 执行结束之后才继续执行;

  • 进程回收

  • wait 函数

  • waitpid 函数

转载地址:http://giznl.baihongyu.com/

你可能感兴趣的文章
GetSchema取得数据库架构,无法取得列的Description属性的解决方法
查看>>
cmd for 循环拷贝文件
查看>>
[Cocoa]深入浅出Cocoa之多线程NSThread
查看>>
c++,不能声明为虚函数的函数
查看>>
Generator函数的语法以及异步的应用
查看>>
【思维导图-索引篇】搞定数据库索引就是这么简单
查看>>
dayjs 源码解析(一)(api)
查看>>
3分钟搭建个人博客
查看>>
JAVA写HTTP代理服务器(三)-https明文捕获
查看>>
The only supported ciphers are AES-128-CBC and AES-256-CBC
查看>>
Kotlin成为正式的Android编程语言
查看>>
微软必应从.NET Core 2.1获得了性能提升
查看>>
Oracle宣布提供新的Java支持价格体系
查看>>
专访1药网技术副总裁黄哲铿:揭秘技术跨界管理之道
查看>>
Markdown通用的常用语法说明
查看>>
PHP:echo、print、print_r() 和 var_dump()
查看>>
Swift中一个类中的枚举(enum)类型的数据该如何实现序列化(NSCoder)
查看>>
WebSocket 原理
查看>>
[LeetCode/LintCode] Factorial Trailing Zeros
查看>>
gulp前端自动化工具的快速入门案例
查看>>