【校招 --阶段一 操作系统基础】继进程概念

通过系统调用创建进程-fork初识创建子进程

#include
#include

pid_t fork( void)

给父进程返回子进程的pid,给子进程返回0
返回值
【校招 --阶段一 操作系统基础】继进程概念_第1张图片

fork有两个返回值
父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)

int main()
{
int ret = fork();
printf("hello proc : %d!, ret: %d\n", getpid(), ret);
sleep(1);
return 0;
}

【校招 --阶段一 操作系统基础】继进程概念_第2张图片
主进程从main函数开始运行是一个执行分支,在fork()之后创建子进程成了两个执行分支。

#include
#include
int main(){
printf("一个分支\n");
fork();
printf("两个分支\n");
return 0;
}




在这里插入图片描述
第二个printf语句执行了两边。

include<stdio.h>
#include
int main(){
printf("一个分支\n");
pid_t ret=fork();
printf("pid:%d,ppid:%d,ret:%d\n",getpid(),getppid(),ret);
printf("两个分支\n");
return 0;
}

在这里插入图片描述
给父进程返回子进程的pid:14996,给子进程返回0。

fork 之后通常要用if 进行分流

#include 
#include 
#include 
int main()
{
int ret = fork();
if(ret < 0){
perror("fork");
return 1;
}
else if(ret == 0){ //child
printf("I am child : %d!, ret: %d\n", getpid(), ret);
}else{ //father
printf("I am father : %d!, ret: %d\n", getpid(), ret);
}
sleep(1);
return 0;
}

【校招 --阶段一 操作系统基础】继进程概念_第3张图片
创建子进程fork()函数给父进程返回的的是子进程pid所以执行的是else语句给子进程返回的是0所i执行的是第二个分支

问题:

  • 1 如何理解创建进程?
    创建进程,是系统多了一个进程,多了一个进程系统就要多一组管理进程的数据结构+该进程对应的数据和代码

  • 2 fork()为什么会有两个返回值?
    fork函数的return语句父进程执行,子进程也要执行,函数的返回值是数据,各自私有一封

  • 3 fork父子执行顺序和代码和数据复制的问题
    进程数据=代码+数据
    父进程创建子进程的时候吗,代码是共享的,数据是各自私有一份(写实拷贝)。通过数据私有表现进程的独立性
    代码是逻辑一般不可修改
    数据是可以修改

  • 4 为何给父进程返回子进程的pid,给子进程返回0

进程状态

看看Linux内核源代码怎么说
为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在
Linux内核里,进程有时候也叫做任务)。
下面的状态在kernel源代码里定义:

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
  • R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列
    里。
  • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠
    (interruptible sleep))。
  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的
    进程通常会等待IO的结束。
  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可
    以通过发送 SIGCONT 信号让进程继续运行。
  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

问题:

  • 是R状态的进程,一定在CPU上跑吗?
    R:可以直接被调度
    不一定
    并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列
    里。

进程状态查看

ps aux | ps axj 命令

【校招 --阶段一 操作系统基础】继进程概念_第4张图片
僵尸进程

问题:

为什么要有僵尸状态?
保持进程基本退出信息,方便父进程读取,获取退出原因
进程死亡,父进程(系统调用,os,检测进程运行完的时候,结束情况,(1 是否正常结束 2 是否异常 3 发生了什么异常))
有什么特征?
一般僵尸进程,task_struct是会被保留下来,进程的退出信息,是放在进程控制快中。

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)
没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

#include 
#include 
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 1;
}
else if(id > 0){ //parent
printf("parent[%d] is sleeping...\n", getpid());
sleep(30);
}else{
printf("child[%d] is begin Z...\n", getpid());
sleep(5);
exit(EXIT_SUCCESS);
}
return 0;
}

【校招 --阶段一 操作系统基础】继进程概念_第5张图片
子进程的状态由S变为Z了

孤儿进程

#include 
#include 
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 1;
}
else if(id > 0){ //parent
printf("parent[%d] is sleeping...\n", getpid());
sleep(30);
}else{
printf("child[%d] is begin Z...\n", getpid());
sleep(5);
exit(EXIT_SUCCESS);
}
return 0;
}

【校招 --阶段一 操作系统基础】继进程概念_第6张图片
如果父进程没有父进程,但是该进程退出,进入僵尸,该进程的资源没有办法被回收,内存泄漏.
os考虑了这个问题,孤儿进程,是要被领养的,os,1号进程领养

进程优先级

cpu资源分配的先后顺序,就是指进程的优先权(priority)。
优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整
体性能。

在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容

【校招 --阶段一 操作系统基础】继进程概念_第7张图片
优先级:pri ,ni(nice优先级修正数据)
优先级=pri_old+nice

UID : 代表执行者的身份
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值

PRI and NI:

PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小
进程的优先级别越高
那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
所以,调整进程优先级,在Linux下,就是调整进程nice值
nice其取值范围是-20至19,一共40个级别。

查看进程优先级的命令

ps -al

用top命令更改已存在进程的nice:
例子:
输入top打开top页面
【校招 --阶段一 操作系统基础】继进程概念_第8张图片
按r接着输入要修该优先级的进程的pid号输入3115
在这里插入图片描述
接着输入要修改nice的值回车修改
在这里插入图片描述

【校招 --阶段一 操作系统基础】继进程概念_第9张图片
上下图对比可以看出修改成功
【校招 --阶段一 操作系统基础】继进程概念_第10张图片

竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高
效完成任务,更合理竞争相关资源,便具有了优先级
独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为
并发

环境变量

执行一条命令:1 找到这条命令 2 运行它

./a.out:目的是找到a.out程序
ls 一定有它默认查找路径!Path环境变量中,环境变量也是变量(变量名Path+变量内容(路径))

是什么?
系统中的某些具有一定全局性质的变量,通常是为了满足摹写系统要求
为什么?
系统的全局变量,都是为了方便用户,系统进行的最简单化的查找,定位
怎么办?

命令行:

env:显示所有环境变量
export导出环境变量
还有其他常见的环境变量PAth SHELL HOME

C语言获取:

在这里插入图片描述
框中为命令行参数 ls为可执行程序

int main(int argc ,char *argv,char*env[]){


return 0
}

【校招 --阶段一 操作系统基础】继进程概念_第11张图片

你可能感兴趣的:(校招,linux,c语言,linux,操作系统)