嵌入式Linux开发:进程、进程间通信

学习视频 <— 众所周知B站是中国最大的学习网站 2333

快速浏览

  • 第一部分:进程基础知识
      • 1.进程的概念
      • 2.进程的内容
      • 3.进程的类型
      • 4.进程的状态
      • 5.进程的Linux命令
  • 第二部分:进程 Linux C 编程
      • 1.fork函数创建子进程
      • 2.exit或_exit函数结束进程
      • 3.exec函数族
      • 4.进程回收
      • 5.守护进程
  • 第三部分:进程间通信

第一部分:进程基础知识

1.进程的概念

● 程序

➢存放在磁盘上的指令和数据的有序集合(文件)
➢静态的

● 进程

➢执行一个程序所分配的资源的总称
➢进程是程序的一次执行过程
➢动态的,包括创建、调度、执行和消亡

2.进程的内容

嵌入式Linux开发:进程、进程间通信_第1张图片
在系统数据段中包含以下部分:进程控制块、CPU寄存器值、堆栈

● 进程控制块(pcb)

➢进程标识PID
➢进程用户
➢进程状态、优先级
➢文件描述符表

3.进程的类型

● 交互进程:在shell下启动。 以在前台运行,也可以在后台运行

● 批处理进程:和在终端无关,被提交到一个作业队列中以便顺序执行

● 守护进程:和终端无关,一直在后台运行

4.进程的状态

● 运行态:进程正在运行,或者准备运行

● 等待态:进程在等待一个事件的发生或某种系统资源

➢可中断	
➢不可中断

● 停止态:进程被中止,收到信号后可继续运行

● 死亡态:已终止的进程,但pcb没有被释放

● 进程状态转换
嵌入式Linux开发:进程、进程间通信_第2张图片

5.进程的Linux命令

● ps:查看系统进程快照

ps -ef					#列出所有进程
ps -ef|grep xxx			#显示xxx程序的进程
ps aux|grep xxx			#显示xxx程序的进程 (增加了状态显示)
man ps					#显示ps命令的相关内容

进程状态码含义
嵌入式Linux开发:进程、进程间通信_第3张图片
● top:查看进程动态信息

top		#每隔3秒刷新进程状态,同时会实时统计进程,按资源占用率排列

按键q或者ctrl+z退出top命令

● /proc:查看进程详细信息

cd /proc	#打开proc文件夹
ls			#会显示很多数字名文件夹

● nice:按用户指定的优先级运行进程

● renice:改变正在运行进程的优先级

renice -n 优先级 进程PID		#修改进程优先级

● jobs:查看后台进程

● bg:将挂起的进程在后台运行

● fg:把后台运行的进程放到前台运行

第二部分:进程 Linux C 编程

1.fork函数创建子进程

● 父进程与子进程的概念

一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原进程(父进程几乎完全相同的进程(子进程),也就是说两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。一个进程调用fork()函数后,系统先给子进程分配资源,例如存储数据和代码的空间,然后把父进程的所有值都复制到子进程中,相当于克隆了一个自己,只有少数值与父进程的值不同,比如PID和PPID父子进程不同。

父进程与子进程的运行(重要)

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

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

  • 若父进程先结束

     ➢子进程成为孤儿进程,被init进程收养
     ➢子进程变成后台进程
    
  • 若子进程先结束

     ➢父进程如果没有及时回收,子进程变成僵尸进程
    
  • 子进程从何处开始运行?

     ➢子进程被fork函数创建出来后,从fork的下一条语句开始执行
    
  • 父子进程谁先执行?

     ➢不确定,由于内核来调度
    
  • 父进程能否多次调用fork? 子进程呢?

     ➢都是可以的,编程时要注意回收子进程
    
#include 		

pid_t pid=fork();		
➢创建新的进程,失败时返回-1.
➢成功时父进程返回子进程的进程号,子进程返回0
➢通过fork的返回值区分父进程和子进程

2.exit或_exit函数结束进程

● 说明
两种方法都可以结束当前的进程并将status返回,当使用exit结束进程时会刷新(流)缓冲区,即内容仍会被写入文件中;而_exit结束进程时,如果缓冲区里的内容还没有写入文件中,缓冲区信息丢失,则不会写入文件里。

#include 
#include 

void exit(int status); 
void _exit(int status);

3.exec函数族

● 说明

  • 函数族是指一组函数

  • 进程可以通过调用exec函数族的函数执行别的程序

  • 进程当前内容被指定的程序替换

  • 实现让父子进程执行不同的程序

     ➢父进程创建子进程
     ➢子进程调用exec函数族
     ➢父进程不受影响
    

● execl函数 / execlp函数

● execv函数 / execvp函数

● system函数

➢比前几种方法简单易用
➢成功时返回命令command的返回值;失败时返回EOF
➢当前进程等待command执行结束后才继续执行
#include 

int system(const char *command);

4.进程回收

● 说明

➢子进程结束时由父进程回收
➢孤儿进程由init进程回收
➢若没有及时回收会出现僵尸进程

● wait函数

➢成功时返回回收的子进程的进程号;失败时返回EOF
➢若子进程没有结束,父进程一直阻塞
➢若有多个子进程,哪个先结束就先回收
➢要回收几个子进程就需要调用几次wait函数
➢status指定保存子进程返回值和结束方式的地址
➢status为NULL表示直接释放子进程PCB,不接收返回值
#include 

pid_t wait(int *status);
  • 举例
int status; 	//用来接收返回值和结束方式
pid_t pid;		
if (pid = fork())<0)	//判断进程创建是否成功
{
	perror("fork"); exit(-1);
}
else if (pid == 0) 		//是否是子进程
	{
		sleep(1); 		//睡眠1秒
		exit(2);
	}
	else 				//主进程
	{
		wait(&status); printf("%x\n", status);
	}
  • 子进程通过exit/_ _exit / return 返回某个值(0-255)

  • 父进程调用wait(&status)回收

      ➢WIFEXITED(status)			判断子进程是否正常结束
      ➢WEXITSTATUS(status)			获取子进程返回值
      ➢WIFSIGNALED(status)			判断子进程是否被信号结束
      ➢WTERMSIG(status)			获取结束子进程的信号类型
    

● waitpid函数

➢成功时返回回收的子进程的pid或0;失败时返回EOF
➢pid可用于指定回收哪个子进程或任意子进程
➢status指定用于保存子进程返回值和结束方式的地址
➢option指定回收方式,0(阻塞)或WNOHANG(非阻塞)
#include 

pid_t waitpid(pid_t pid,int *status,int option);
  • 举例
waitpid(pid, &status, 0);
waitpid(pid, &status, WNOHANG); 
waitpid(-1, &status, 0);
waitpid(-1, &status, WNOHANG);

5.守护进程

● 概念

➢守护进程(Daemon)是Linux三种进程类型之一
➢通常在系统启动时运行,系统关闭时结束
➢Linux系统中大量使用,很多服务程序以守护进程形式运行

● 特点

➢始终在后台运行
➢独立于任何终端
➢周期性的执行某种任务或等待处理特定事件

● 会话、控制终端

➢Linux以会话(session)、进程组的方式管理进程
➢每个进程属于一个进程组
➢会话是一个或多个进程组的集合。通常用户打开一个终端时,
  系统会创建一个会话。所有通过该终端运行的进程都属于这个会话

● 创建守护进程

(待续)

第三部分:进程间通信

(待续)

你可能感兴趣的:(嵌入式Linux,C/C++)