嵌入式学习DAY25 --- 进程线程开始学习,进程的基本概念以及创建退出_嵌入式需要学进程吗(1)

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

程序:
程序是静态的一段代码
是一些保存在非易性存储器的指令的有序集合
没有任何执行的概念

进程:
是一个动态的概念
是程序执行的过程,包括动态创建,调度和消亡的整个过程。
它是资源分配的最小单元。

并发编程的核心:

1.程序执行的过程
CPU、总线、内存
三者如何执行指令见计算机组成原理

2.并发编程中的核心问题

多任务如何共享CPU
单核CPU
多核CPU
多任务如何共享内存(有操作系统)
默认有一份虚拟地址空间

多进程主要问题是如何共享一份虚拟地址空间
进程间切换:
主要是同一份虚拟地址空间的上下文切换
->保存上文
保存上一个进程的运行状态
->加载下文
加载下一个程序到内存中
进程上下文切换发生在以下几个情况中:
a进程执行完,b进程执行
a进程时间片到了,b进程执行
a进程被中断,优先执行b进程

CPU调度算法:

公平调度策略:
是按照时间片轮转的方法来实现多任务调度

抢占式任务调度:
有优先级,优先级即高的可以抢占优先级低的进程的执行资源。

Linux下进程的分类:

1.交互式进程
2.批处理进程
3.实时进程

进程的地址空间:

Linux操作系统采用的是虚拟内存管理技术,使得每个进程都有独立的地址空间。该地址空间是大小为4G的线性虚拟空间,用户所看到和接触到的都是该虚拟地址。无法看到实际的物理内存地址。利用这种虚拟地址不但更安全(用户不能直接访问物理内存),而且用户程序可以使用比实际物理内存更大的地址空间。
4GB的进程地址空间会被分成两个部分——用户空间与内核空间。用户地址空间是0~3G(0xC0000000),内核地址空间占据3-4GB。用户进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间虚拟地址。只有用户进程使用系统调用(代表用户进程在内核态执行)时,才可以访问到内核空间。每当进程切换,用户空间就跟着变化;而内核空间是由内核负责用设,它并不会随着进程改变,是固定的。内核空间地址有自己对应的页表,用户进程各自有不同的页表。每个进程的用户空间都是完全独立、互不相干的。

Linux,进程开辟个数的上线:
为了与老版本兼容,short int pid,32768
可以修改上线:
修改这个文件:/proc/sys/kernel/pid_max

Linux下进程的状态:
如何查看Linux 进程状态:
ps:静态查看进程信息
ps -aux
ps -ajx (SID)
top:动态查看活跃的进程信息
pstree:显示进程的父子关系/打印进程树
kill:给指定进程发送信号,查看Linux提供的信号

ps命令的输出内容:
	PPID:父进程ID       				*
	PID:进程ID 							*
	PGID:进程组ID 						*
	SID:会话组ID(会话期ID) 				*
	TTY:终端							*
	STAT:进程状态						*
			进程状态,用下面的代码中的一个给出:
			D    不可中断     Uninterruptible sleep (usually IO)
			R    正在运行,或在队列中的进程
			S    处于休眠状态
			T    停止或被追踪
			Z    僵尸进程
			W    进入内存交换(从内核2.6开始无效)
			X    死掉的进程
			<    高优先级
			N    低优先级
			N    低优先级
			L    有些页被锁进内存
			s    包含子进程
			+    位于后台的进程组
			l    多线程,克隆线程

	UID:进程的用户ID
	TIME:进程使用的总CPU时间
	COMMAND:执行进程时的命令
	USER:进程所有者
	%CPU:进程自最近一次刷新以来所占用的CPU时间和总时间的百分比
	%MEM:进程使用内存的百分比
	VSZ:进程使用的虚拟内存大小,以K为单位
	RSS:驻留空间的大小。显示当前常驻内存的程序的K字节数
	START:进程的起始时间
	NI	进程的优先级值,较小的数字意味着占用较少的CPU时间
	PRI	进程优先级。
	WCHAN	进程等待的内核事件名

Linux进程状态:
	运行态
	停止态
	僵尸态
	死亡态
	阻塞态
		可中断的阻塞态
		不可中断的阻塞态

进程信息存在:/proc目录下

进程的创建
进程创建技术:
1.完美拷贝
几乎拷贝父进程的所有内容,除了父进程的PID,PCB信息
2.写时拷贝
开辟好进程基本管理信息后,共享父进程的数据和代码,只有
需要更改时,才拷贝
较为节省内存开销,所以用的较多
Linux 2.6版本之后,大多使用写时拷贝

fork:
	/*需要包含的头文件*/
	#include <unistd.h>
	/*
	 *函数名:fork
	 *函数功能:创建子进程
	 *函数参数:void
	 *函数返回值:pid_t
	 *		>0: 父进程,代表子进程的pid
	 *      ==0: 子进程
	 *      -1: fork失败
	 */
	pid_t fork(void);


vfork
clone
system:<在正式工作时,不建议使用,容易产生死锁>
	/*需要包含的头文件*/
	#include <stdlib.h>
	/*
	 *函数名:system
	 *函数功能:fork一个子进程,执行一条shell指令
	 *函数参数:const char *command:指令内容
	 *函数返回值:int:见manual
	 */
	int system(const char * command);
sleep():
	/*需要包含的头文件*/
	#include <unistd.h>
	/*
	 *函数名:sleep
	 *函数功能:让进程/线程睡眠指定的秒数
	 *函数参数:unsigned int seconds:指定睡眠的秒数
	 *函数返回值:unsigned int:成功返回sleep的时间,失败返回0			
	 */
	 unsigned int sleep(unsigned int seconds);
fork():
	1.创建一个子进程
	2.2.6以后用写时拷贝,之前用完美拷贝
	3.子进程和父进程执行顺序不确定
	4.有两个返回值,
		>0:为父进程,返回值代表子进程的pid
		==0:为子进程,返回值为0
vfork():
	1.创建子进程,阻塞父进程
	2.子进程先执行
	3.使用的是写时拷贝
	4.有两个返回值,
		>0:为父进程,返回值代表子进程的pid
		==0:为子进程,返回值为0

clone():
	不管是fork()还是vfork(),底层实现都是clone()
	该函数返回子进程的进程号,可以有选择性的拷贝
	父进程的内容。

system():
	fork() + execl()
	创建一个进程,并执行一个shell命令
	不建议执行耗时命令,容易产生死锁的情况

进程的执行

exec函数族:
一般用来执行程序,而不是程序员自己灵活编写的代码
要求执行的是可执行文件。
当判断是否为子进程时,直接写相应的代码
这种方式比较灵活
system
同execl,但容易发生死锁
exec x x:
l e
v p
第五位的选项:
l:命令行参数以枚举形式输入,包含命令本身,以NULL结尾
v:命令行参数以指针数组形式传入,即把list内容写入指针数组
第六位的选项:
e:在指定的位置中执行查找可执行文件
p:在系统环境变量中执行查找可执行文件

exec函数族只能执行指定的可执行文件,是一种不够灵活的执行特定任务
的方法,掌握 execve execlp就可以了

进程的销毁
exit:
	调用退出处理函数
	清理I/O缓冲区
_exit:
	没有上述操作	

获取进程表识:
#include <sys/types.h>
#include <unistd.h>

获取当前进程的pid
pid_t getpid(void);
获取父进程的pid
pid_t getppid(void);

标准IO缓冲区:
缓冲区的分类:
全缓冲:普通文件
行换成:stdin,stdout
无缓冲:stderr
ANSI C(C89)要求缓冲具有以下特点:
1.当且仅当标准输入和标准输出并不涉及交互设备时,它们才可以使用全缓冲。

这里并没有交代如果标准输入和标准输出涉及交互作用设备时,它们使用无缓冲还是行缓冲。

大多数系统默认使用下列类型的缓冲区:
1.标准错误是不带缓冲区的
2.如果涉及终端设备的流,则它们是行缓冲的
3.否则是全缓冲

注意:终端牵扯标准输入/输出流(stdin/stdout)

在我们使用的linux/ubuntu中:
全缓冲的大小为:4096 Byte
行缓冲的大小为:1024 Byte

如何验证全缓冲的大小:
原理:缓冲区存不下数据的时候,会刷新缓冲区(正常情况)
注意:为了避免进程退出刷新缓冲区,需要_exit()函数来做这件事情
或者使用while(1)还阻塞进程,防止进程退出(不建议使用,比较难理解)

例子:

#include <stdio.h>
		#include <unistd.h>

		int main()
		{
		        FILE \*fp = NULL;
		        fp = fopen("a.txt","r+");
		        if(NULL == fp)
		        {
		                puts("open file error.");
		                return -1;
		        }

		        int i = 0;
		        //当缓冲区中的数据<=4096,在没有其他强制刷新的情况下,不会
		        //清空缓冲区,只有当缓冲区中的数据>4096个字符时,才会刷新
		        for(i = 0; i < 4096; i++)
		        {
		                fputc('a',fp);
		        }
		        \_exit(0);
		}

	输出结果:执行之后,a.txt没有写入数据
		-rw-rw-r-- 1 farsight farsight    0 May  6 19:37 a.txt

	上面的实验结果说明:缓冲区没有满,数据没有写入,也证明了大小为4096

#include <stdio.h>
		#include <unistd.h>

		int main()
		{
		        FILE \*fp = NULL;
		        fp = fopen("a.txt","r+");
		        if(NULL == fp)
		        {
		                puts("open file error.");
		                return -1;
		        }

		        int i = 0;
		        //当缓冲区中的数据<=4096,在没有其他强制刷新的情况下,不会
		        //清空缓冲区,只有当缓冲区中的数据>4096个字符时,才会刷新
		        for(i = 0; i < 4200; i++)
		        {
		                fputc('a',fp);
		        }
		        \_exit(0);
		}

	输出结果:执行之后,a.txt写入数据,并且只写了缓冲大小个数据
    	-rw-rw-r-- 1 farsight farsight 4096 May  6 19:39 a.txt

如何验证行缓冲的大小:
原理:同全缓冲的原理

例子:

#include <stdio.h>
		#include <unistd.h>

		int main()
		{
				//当缓冲区中的数据<=1024,在没有其他强制刷新的情况下,不会
		        //清空缓冲区,只有当缓冲区中的数据>1024个字符时,才会刷新
		        int i = 0;
		        for(i = 0; i < 1024; i++)


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/a2726d6385c7e25b26dac93e7089f3d4.png)
![img](https://img-blog.csdnimg.cn/img_convert/35c99cf20ff587aa1161fac0fd69b002.png)

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

不会
		        //清空缓冲区,只有当缓冲区中的数据>1024个字符时,才会刷新
		        int i = 0;
		        for(i = 0; i < 1024; i++)


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
[外链图片转存中...(img-XKxdaxLs-1715716483214)]
[外链图片转存中...(img-ohyTRSNJ-1715716483215)]

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值