并发 进程

程序执行方式:

1.顺序执行 :一个程序执行完,才能执行下一个程序。cpu利用率低
2.并发执行 :  一个程序执行有很多步骤,取值 -> 执行 ->写回
					不同的步骤需要不同的硬件完成,使用并发就可以实现多个程序同时执行,这里就引入了‘进程’这个概念,提高cpu的利用率

进程和程序的区别 :

(1) 程序是静态概念(是指令与数据的有序集合,“程序文件”)
	进程是动态的概念,进程是有声明周期的(动态产生,动态消亡)
(2) 进程是一个程序的一个执行活动。
	一个程序可以对应多个进程。 
(3) 进程是独立的活动单位;
	进程是竞争资源的基本单位。

进程的状态

	就绪态(Ready):准备工作已经做好了,只要有CPU,就可以工作。
	运行态(Running):cpu正在执行这个进程的指令
	阻塞态(Blocking或waiting):进程正在等待外部事件的发生。	
	creat产生进程 ->  Ready   ------->  Running --------> Blocking --------> ...

就绪队列:

	所有处于 “ ready ” 状态的进程,都存在一个“ 后备队列”

调度策略:

进程是 任务的调度最小单位,负责资源的分配和管理
分时系统:
		调度策略以"时间片轮转",为主要的策略的系统"时间片轮转" : 分时, 每一个进程执行一段时间(时间片)
实时系统: 
		调度策略以“实时策略”为主的系统
		“实施策略”:每次调度都去优先级高的那个进程,直到这个进程执行完毕或它主动放弃CPU或者比他更高的优先级的进程抢占。			
抢占: 插队

进程的执行
进程执行的第一件事就是申请一块空间来存储程序的数据,不同的‘数据’ ,需要分区域保存。

linux进程的地址空间布局
	“分段” : 分不同的逻辑区域
	Linux对进程的数据进行分段管理,不同的属性的数据,存储在
	不同的“内存段”中, 不同的“内存段”的属性是不同的,so不同的
	“内存段”的管理的方式也不一样。
.text 
	主要是用来存放代码。
	只读并且共享。这段内存在进程运行期间,不会释放的“代码段” 随进程持续性。	
.data
	数据段。
	主要存放程序的 已经初始化的全局变量 和 已经初始化的static变量
	可读可写。这段内存在进程运行期间,一直存在,随进程持续性的。	
.bss
	数据段。 
	主要存放程序的 没有初始化的全局变量 和 没有初始化的static变量
	可读可写。这段内存在进程运行期间,一直存在,随进程持续性的。.bss,在进程初始化的时候,(可能)全部初始化为0。	
.rodata : 
	只读数据段
	主要存放程序中的只读数据的(如: 字符串常量)
	只读。这段内存在进程运行期间,一直存在。随进程持续性。
栈(Stack)空间:
	主要存放局部变量(非static的局部变量)
	可读可写。这个段空间,会自动释放(代码块执行完啦,代码中的局部变量的空间就会被自动释放)。随代码块持续性的。
堆(Heap)空间: 动态内存空间
	主要是malloc/realloc/calloc动态分配的空间。
	可读可写。这段内存在进程运行期间,一旦分配,就会一直存在,直到你手动free或进程消亡。 
	
	防止 "内存泄漏" / "垃圾内存"

linux下面关于进程的一些API函数

1.创建一个进程   
	./test 
		 运行一个  .c 编译的程序
	在程序中 创建子进程
		函数原型 
			pid_t  fork(void);
		返回值:
			成功父进程返回 子进程pid (> 0)
			成功子进程返回 0
			失败返回  -1  同时error被设置			
		子进程会复制父进程的fork以下的所有代码,以及缓存区的所有内容,和定义的变量。
		函数:
		pid_t getpid(void);//用于获取自己的进程ID
 		pid_t getppid(void);// 用于获取父进程的ID 	
 	2.进程退出
 		2.1.自杀
 			a、main函数返回,进程退出
 			b、在进程执行的任意时刻,调用进程退出函数
 					void exit(int status)  //正常退出,做一些清理工作
 					void _exit (int status) // 非正常退出
 		2.2 他杀
			一般是被操作系统杀死
	3.等待子进程退出
		fork()执行之后,父子进程的执行先后同样是由系统调用,可能父进程执行完
		pid_t wait(int *wstatus);
  		pid_t waitpid(pid_t pid, int *wstatus, int options);  
   这两个函数用来等待某个(些)子进程的状态发生改变的,等待 的状态发生改变有三种情况: 
		a、子进程退出(正常退出):main函数返回/exit/_exit
		b、子进程被信号中止<>
		c、子进程被信号唤醒(Blocking -> Ready)
	一个进程的退出,操作系统会释放它的大部分的资源,但是有一小部分必须留给它父进程去释放。在子进程正常退出(a)情况,调用wait/waitpid 可以释放子进程的资源。
	未使用此函数可能导致:两种进程的产生。
	僵死(僵尸)进程:
		如果一个进程退出了,但是父进程没有调用wait/waitpid,这个进程就会变成僵尸进程:已经死啦,但是资源没有被完全释放掉。
	孤儿进程:
		父进程结束,子进程还没结束。
函数:
	----------------------------------------------------------------
	 pid_t wait(int *wstatus);
		 wstatus: 指针。用来保存子进程的退出信息的(退出码)
	返回值: 
		成功返回退出的子进程的ID
		失败返回-1,errno被设置。
	-----------------------------------------------------------------
	pid_t waitpid(pid_t pid, int *wstatus, int options);
		pid : 指定要等待的进程或进程组
			pid == -1, 表示等待任意的子进程退出
			pid == 0 , 表示等待与调用进程同组的任意子进程
				"进程组":
					就是是一组进程。每一个进程必定会属于一个进程组。并且每个进程组,都会有一个组长进程,
					一般来说,创建这个进程组的进程为组长,进程组有一个组ID,这个组ID,就是进程组长的ID.
			pid < -1, 表示等待组ID等于pid的绝对值的那个组的任意子进程退出。	
						如: 
							pid == -1028
							等待进程组号1028的那个组内的任意的子进程
			pid > 0 , 表示等待pid指定的子进程
						如:
							pid == 1024
							等待pid为1024的这个子进程			
		status: 同上 
		options : 等待选项 
			0 : 表示阻塞等待(默认阻塞等待)
			WNOHANG: 非阻塞,假如没有子进程退出,则立刻返回。
		返回值: 
			成功返回退出的子进程的ID
			失败返回-1,errno被设置。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值