Linux 进程编程

进程相关

程序: 静态的,是有序数据指令的集合
进程: 是系统分配资源的总称,进程是程序执行的一次完整的过程(创建 调用 执行 消亡)

程序的组成: 正文段 用户数据段
1)进程的组成: 正文段 用户数据段 系统数据段(进程控制块PCB,PC,堆栈)

    PCB:
		进程ID 用户名 用户组名 进程的状态 优先级 文件描述符表
    PC:程序寄存器
        记录程序下一条指令的地址
    堆栈()  

2)进程的类型
交互进程:  跟终端相关,可以在前台运行,也可以在后台运行
批处理进程: 跟终端无关,可以将指定的进程放在一个工作队列中按顺序执行,一般由系统管理员
守护进程:  跟终端无关,在后台一直循环执行任务

3)进程的状态
R(Runnable)  运行态(就绪态):正在运行或者准备运行的程序

等待态: 两种等待态区别在于是否能被信号打断
 S(Sleeping)       可中断等待态
 D(Uninterruptible sleep) 不可中断等待态

T(Terminate)  暂停态:暂停运行,直到有信号唤醒为止
Z(Zombie)   僵尸态: 进程已终止,进程描述符还存在

1. 进程相关指令:
ps -ef		查看当前系统进程
ps -aux 	查看当前系统进程,会显示进程状态
top			动态显示进程实时信息
ps -fp "1 2 3"		查看进程号1 2 3的进程信息
ps -fp 1,2,3		查看进程号1 2 3的进程信息
pidof ./a.out		打印 ./a.out 进程的pid及子进程pid
ps -fp "`pidof ./a.out`"	查看./a.out程序和其子程序的信息
   -f 完整格式清单(含父进程号ppid)
   -e 全部进程
2. 进程的优先级

进程的优先级取值范围: [-20 ~ 19],默认值为0

  nice -n 2 ./a.out    //在准备运行时,将 a.out 的优先级设为 2
renice -n 2 进程号      //在运行过程中,将 a.out 的优先级设为 2
3. 前后台进程切换
./a.out &	  令a.out在后台运行
jobs		  查看后台任务
bg + 任务号	将后台挂起的进程唤醒	background
fg + 任务号	将后台运行的进程切换到前台运行	 foreground
4. 进程相关接口函数

1) 创建子进程 fork()
#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

返回值:
	成功创建一个新的子进程,父进程返回子进程的pid,子进程返回 0;
	失败父进程返回-1, 子进程不被创建

父子进程:

​ 一个进程通过 fork() 函数创建一个新进程,原本进程成为新进程的父进程,新进程称为原进程的子进程。子进程会继承父进程中几乎所有数据。

1) 如果父进程优先子进程结束:

① 子进程成为孤儿进程;
② 由前台进程变为后台进程;
③ 统一为init进程收养

2) 如果子进程优先父进程结束,且父进程没有回收子进程资源

① 子进程状态变成僵尸进程(僵尸态)

1. 一般来说,如果子进程先于父进程结束,子进程应该统一由父进程回收

2. 子进程在fork语句的下一条指令开始执行

2) 结束进程 exit() / _exit()
#include <stdlib.h>

void exit(int status);
参数:
	status:		表示进程退出的状态
#include <unistd.h>
void _exit(int status);

exit() 函数调用后会刷新所有缓冲区, _exit() 函数不会刷新

在这里插入图片描述

3) 进程回收 wait() / waitpid()
int wstatus;
wait(&wstatus);
#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *wstatus);
返回值:
	成功返回结束子进程的pid号, 失败返回 -1
参数:
	wstatus:	表示进程结束时,状态信息的地址

得到子进程结束的状态信息:
	WIFEXITED(wstatus)		判断是否正常退出 true or false
    WEXITSTATUS(wstatus)  	返回子进程结束的返回值
    WIFSINALED(wstatus)		判断是否通过信号退出 true or false
	WTERMSIG(wstatus)		返回信号终止的信号编号

int wstatus;
waitpid(-1, &wstatus, 0); //等同于	wait(&wstatus);
#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *wstatus, int options);
返回值:
参数:
	pid:	 进程号, -1表示接收任意子进程
    wstatus: 进程结束时,状态信息的地址
    options:
		0		以阻塞的方式等待子进程结束
        WNOHANG	以非阻塞的方式等待子进程结束
4) exec 函数族
#include <unistd.h>

l:	list列表
v:	argv
p:	PATH
-------------------------------------------------------------------------
int execl(const char *pathname, const char *arg, .../* (char  *) NULL */);
eg.
	execl("ls", "ls", "-l" ,NULL);

参数:
	pathname:	执行程序的文件名
   	arg:		执行程序的命令行参数,命令行参数列表以NULL结尾
返回值:
	失败返回 -1;

-------------------------------------------------------------------------
int execlp(const char *file, const char *arg, .../* (char  *) NULL */);
参数:
	file:	程序名
添加环境变量:~/.bashrc中添加命令:
		export PATH=$PATH:/home/...
    配置完成后,令配置重新生效:
		source ~/.bashrc
            
-------------------------------------------------------------------------
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
5. 守护进程

在这里插入图片描述

​ 守护进程跟中断无关,负责在后台周期性的处理某些事件或者等待某些事件相应

​ 1)进程组:当用户运行一个进程时,就相当于创建了一个进程组,跟该进程具有亲缘关系的所有进程都属于该进程组;

​ 2)会话: 当用户打开一个终端时,就创建了一个会话,一个会话由一个或多个进程组成,一旦终端关闭,该会话中所有进程组中的进程全部结束

守护进程的创建流程

1.创建子进程,父进程退出 fork();

2.让子进程脱离原本会话 setsid();

3.修改当前工作路径 [非必要] chdir(“path”);

4.重设文件权限掩码 [非必要] umask(0);

5.删除进程中所有的文件描述符
getdtablesize() -- get file descriptor table size 获取文件描述符表大小

int i = 0;
for(i = 0; i < getdtablesize(); i++)
    close(i);

while(1)
{
    /* 周期性执行语句 */
}
  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值