进程控制1

进程控制

1,什么是进程:进程是可并发执行的程序,是一个在数据集合上的运行进程
当一个程序开始执行后,在开始执行到执行结束的这段时间里,它内存中的部分被称为进程
通俗讲:程序就是在硬盘上的可执行文件
进程就是在执行中的程序

2,什么是并发:多个进程同时运行,多个任务同时执行

3,虚拟内存
Linux虚拟内存管理技术:
物理内存:实际在处理器中的内存模块 几百M
将硬盘中的一部分存储单元来当做内存使用 4个G (受操作系统的寻址范围影响)
0x000000——0xffffff
操作系统:用户空间和内核空间
内核空间:高地址 1g
用户空间:低地址 3g
虚拟内存管理技术的好处:
1,有效防止内核空间被破坏
2,防止被恶意窥探(作为对硬盘的映射,)
3,不会因为拿走硬盘被发现数据
虚拟地址的组成:物理地址+偏移量(rel)
4,拓展内存空间

4,进程的分类
1,守护进程
2,批处理进程
3,交互进程
5,进程的属性
进程的ID(PID进程号):是唯一的属性,用来区分进程
父进程的ID(PPID)
启动进程的用户ID:UID
进程的状态:运行R,休眠S,僵尸进程Z,死掉的进程X,暂停状态T
进程优先级
进程占用资源的大小(内存,CPU)
6,进程控制模板PCB:数据结构
进程号:ps命令查看Linux系统中的进程 (ps -命令)

  1. l:长格式输出
  2. u:接用户名和启动时间的顺序来显示进程
  3. f:用树状格式来显示进程
  4. a:显示所有用户的所有进程
  5. x:显示无控制终端进程
    在这里插入图片描述

%CPU是占用CPU的大小
%MEM是占用内存的多少
STAT是进程的状态
TIME:进程消耗时间

杀死命令:kill
kill +进程号(PID)
kill +进程名 -9:强制终止
pkill :pkill +程序名
xkill:在桌面上杀死图像化界面
renice:改变进程的优先级,通过改变进程ID(PID)来改变谦让度,进而达到改变进程的优先级
renice 谦让度 PID

7,进程的状态转换
(1)就绪:当进程已分配到除CPU以外所有必要资源,只要获得处理器就可以立即执行
(2)执行:已经获取处理器,其程序正在处理器上执行
(3)阻塞:正在执行的进程,由于等待某个事件的发生而无法执行时,便放弃处理机会而处于阻塞状态
并发的本质:时间片轮询
在这里插入图片描述
在这里插入图片描述
8,Linux进程调度
1,FCFS也叫FIFO,先来先处理;缺点:对于短的任务可能变得非常缓慢
2,时间片轮巡算法:周期性的切换总体时长比FIFO短;缺点:过多的短任务会使大量时间耗费在切换任务上
3,STCF:
短任务优先算法
抢占式和非抢占式 缺点:长任务很难拿到CPU资源
4,银行家算法

9,创建一个进程
fork()函数
有两个返回值 0:子进程 -1:失败 >0:父进程
头文件:

#include “unistd.h”

函数原型:

pid_t fork(void);

有两个返回值:

#include"stdio.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdlib.h"

int main()
{
    
    
    pid_t pid =fork();
    if(-1 ==pid)
    {
    
    
	perror("fork error!");
	exit(1);
    }
    if (0 == pid)
    {
    
    
	printf("this is child\n");
    }
    else
    {
    
    
	printf("this is father\n");
    }
}

在这里插入图片描述
getpid:获取当前进程号
getppid:获取当前父进程号
获取进程号和父进程号

#include"stdio.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdlib.h"

int main()
{
    
    
    pid_t pid =fork();
    if(-1 ==pid)
    {
    
    
	perror("fork error!");
	exit(1);
    }
    if (0 == pid)
    {
    
    
	printf("this is child: pid:%d       ppid:%d\n",getpid(),getppid());
    }
    else
    {
    
    
	printf("this is father: pid:%d      ppid:%d\n",getpid(),getppid());
    }
}

在这里插入图片描述
fork函数运行之后,子进程会复制父进程的堆栈数据空间
父进程与子进程跑在不同的内存空间中:父进程与子进程有自己的独立的内存空间

#include"stdio.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdlib.h"
int main()
{
    
    
    int a=5;
    pid_t pid =fork();
    if(-1 ==pid)
    {
    
    
	perror("fork error!");
	exit(1);
    }
    if (0 == pid)
    {
    
    
	a=a*5;
	printf("this is child: pid:%d       ppid:%d a =%d\n",getpid(),getppid(),a);
    }
    else
    {
    
       a =a-1;
	printf("this is father: pid:%d      ppid:%d a =%d\n",getpid(),getppid(),a);
    }
}

在这里插入图片描述
早期:
fork函数运行之后,子进程会复制父进程的堆栈数据空间
优化:
读时不管,写时复制
父进程子进程所用参数地址相同:

//输出所用参数的地址
#include"stdio.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdlib.h"

int main()
{
    
    
    int a=5;
    int b=100;

    pid_t pid =fork();
    if(-1 ==pid)
    {
    
    
	perror("fork error!");
	exit(1);
    }
    if (0 == pid)
    {
    
    
	a=a*2;
	printf("this is child:  a=%d a addr:%x b=%d b addr:%x \n",a,&a,b,&b);
    }
    else
    {
    
       a =a-1;
	printf("this is father:  a=%d a addr:%x b=%d b addr:%x \n",a,&a,b,&b);
    }
}

在这里插入图片描述

fork函数创建的父子进程关系是竞争关系,不能判断是谁先动

//判断谁快一点
#include"stdio.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdlib.h"

int main()
{
    
    
    int i=0;
    pid_t pid=fork();
    if(-1 == pid)
    {
    
    
	perror("fprk error");
	    exit(1);
    }
    if (0 == pid)
    {
    
    
	for(i=0;i<5;i++)
	{
    
    
	printf("child\n");
	sleep(2);
	}
    }
    else
    {
    
    
	for(i=0;i<5;i++)
	{
    
    
	printf("father\n");
	sleep(2);
	}
    }
}

在这里插入图片描述

vfork():
创建一个进程
1,保证子进程先动

//子进程先动
#include"stdio.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdlib.h"

int main()
{
    
    
    int i=0;
    pid_t pid=vfork();
    if(-1 == pid)
    {
    
    
	perror("fprk error");
	    exit(1);
    }
    if (0 == pid)
    {
    
    
	for(i=0;i<5;i++)
	{
    
    
	printf("child\n");
	sleep(2);
	}
    }
    else
    {
    
    
	for(i=0;i<5;i++)
	{
    
    
	printf("father\n");
	sleep(2);
	}
    }
}

在这里插入图片描述
2,当子进程调用exit()函数后,父进程往下执行
3,不会继承父进程的页面

eg:
1,创建两条进程,一条输出A,一条输出B,交替输出ABABABABAB

#include"stdio.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdlib.h"
int main()
{
    
    
    int i=0;
    pid_t pid=vfork();
    if(-1 == pid)
    {
    
    
	perror("fprk error");
	    exit(1);
    }
    for(i=0;i<5;i++)
    {
    
    
    if (0 == pid)
    {
    
    
	printf("A\n");
	pid =1;
    }
    else
    {
    
    
	printf("B\n");
	pid =0;
    }
    }
    exit(0);
}

在这里插入图片描述
eg:三条进程,ABC交替输出

#include"stdio.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdlib.h"
int main()
{
    
    
    int i=0;
    for(i=0;i<5;i++)
    {
    
    
	pid_t pid =vfork();
	if(-1 == pid)
	{
    
    
	    perror("fprk error");
	    exit(1);
	}
	if(0 == pid)
	{
    
    
	    printf("A\n");
	    exit(1);
	}
	else
	{
    
    int pit =vfork();
	    if(0 == pit)
	    {
    
    
		printf("B\n");
		exit(1);
	    }
	    else
	    {
    
    
		printf("C\n");
	    }
	}
    }
}

在这里插入图片描述
eg:三条进程,ABC交替打印
(我这里认为是输入到文件的意思)

#include"stdio.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdlib.h"
int main()
{
    
    
    int i=0;
    FILE *fp;
    fp =fopen("./text.txt","w+");
    for(i=0;i<5;i++)
    {
    
    
	pid_t pid =vfork();
	if(-1 == pid)
	{
    
    
	    perror("fprk error");
	    exit(1);
	}
	if(0 == pid)
	{
    
    
	    fputs("A",fp);
	    exit(1);
	}
	else
	{
    
    int pit =vfork();
	    if(0 == pit)
	    {
    
    
	    fputs("B",fp);
		exit(1);
	    }
	    else
	    {
    
    
	    fputs("C",fp);
	    }
	}
    }
	    fclose(fp);
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45824568/article/details/115224295