191进程管理

fprintf(格式化输出数据至文件)

函数说明:
fprintf()函数根据指定的format(格式)发送信息(参数)到由stream(流)指定的文件.因此fprintf()可以使得信息输出到指定的文件
返回值:
fprintf()的返回值是输出的字符数,发生错误时返回一个负值.

fcanf(格式化字符串输入)

函数说明:
从一个流中执行格式化输入,fscanf遇到空格和换行时结束,注意空格时也结束。
返回值:
整型,数值等于[argument…]的个数

进程

进程是具有一个独立功能的程序的一次性运行活动,同时也是资源分配的最小单元;

进程与程序

进程是动态的,程序是静态的;
进程是暂时的,程序是长久的;
进程与程序组成不同;
进程与程序的对应关系
进程的特征:动态性:是程序的一次执行;并发性:进程是可以并发执行;独立性:是系统进行资源分配和调度的一个独立单位;异步性:进程间的相互制约,使进程执行具有间隙;结构性:进程是具有结构的。

进程与程序的主要区别:

1.进程包括程序和程序处理的对象(数据集)

2.程序是静止,进程是动态的;

3.进程具有并发性,而程序没有;

4.进程是竞争计算机资源的基本单位,程序不是。

5.进程和程序不是一一对应的:一个程序可对应多个进程即多个进程可执行同一个程序;一个进程可以执行一个或几个程序。

进程的生命周期

创建、运行、撤销

进程的状态

执行状态、就绪状态、等待状态
在这里插入图片描述

Linux进程

Linux系统是一个多进程的系统,它的进程之间具有并行性,互不干扰等特点。
也就是说,每个进程都是一个独立的运行单位,拥有各自的权力和责任。其中,各个进程都运行在独立的虚拟地址空间,因此,即使一个进程发生异常,他也不会影响到系统的其他进程。

Linux下进程地址空间

在这里插入图片描述

进程ID

进程ID(PID):标识进程的唯一数字
父进程的ID(PPID)
启动进程的用户ID(UID)
进程互斥:两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥· 也就是说,一个进程正在访问临界资源,另一个要访问该资源的进程必须等待。
临界资源:操作系统中将一次只允许一个进程访问的资源称为临界资源
进程同步:我们把异步环境下的一组并发进程因直接制约而互相发送消息、进行互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步。具有同步关系的一组并发进程称为合作进程,合作进程间互相发送的信号称为消息或事件。 如果我们对一个消息或事件赋以唯一的消息名,则我们可用过程 wait (消息名)  表示进程等待合作进程发来的消息,而用过程 signal (消息名) 表示向合作进程发送消息。
进程调度:无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。另外,系统进程也同样需要使用处理机。这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。
调度方式:抢占式、非抢占式
调度算法:先来先服务调度算法、短作业(进程)优先调度算法、高优先权优先调度算法、时间片轮转算法
死锁:两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

进程创建

子进程的创建
在Linux中,父进程以分裂的方式来创建子进程,创建一个子进程的系统调用叫做fork()。

系统调用fork()
为了在一个进程中分裂出子进程,Linux提供了一个系统调用fork()。这里所说的分裂,实际上是一种复制。因为在系统中表示一个进程的实体是进程控制块,创建新进程的主要工作就是要创建一个新控制块,而创建一个新控制块最简单的方法就是复制。

当然,这里的复制并不是完全复制,因为父进程控制块中某些项的内容必须按照子进程的特性来修改,例如进程的标识、状态等。另外,子进程控制块还必须要有表示自己父进程的域和私有空间,例如数据空间、用户堆栈等。

vfork(建立一个新的进程)

在使用vfork的时候,可以看到,只有一个 hello andrew输出,以内vfork函数是部位子进程创建单独的分区的而是和父进程共用一个,一旦子进程将缓存区中的内容输出,那么另一位缓存区中也不会在有内容,因为两者缓存区是相同的;
fork()和vfork()的区别联系:

fork() 子进程拷贝父进程的前3G的地址空间的内容.
vfork() 子进程与父进程共享数据段,读写都共享.|
2.
fork() 父子进程的执行次序不确定,最终由调度进程决定.
vfork():保证子进程先运行,父进程会被挂起,直到子进程调用exit()或者exec()系列函数
如果在 调用这两个函数之前子进程有依赖于父进程的进一步动作,则会导致死锁,因为父进程已经被挂起,父进程的运行需要子进程的退出,而子进程的执行又依赖父进程。
3.
vfork用于创建一个新进程,而该新进程的目的是exec一个新进程,通常vfork()和exec搭配使用
vfork和fork一样都创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,不会复制页表。因为子进程会立即调用exec,于是也就不会存放该地址空间。不过在子进程中调用exec或exit之前,他在父进程的空间中运行。

vfork这个系统调用是用来启动一个新的应用程序。
其次,子进程在vfork()返回后直接运行在父进程的栈空间,并使用父进程的内存和数据,这是很危险的操作。

子进程还必须避免改变全局数据结构或全局变量中的任何信息,
因为这些改变都有可能使父进程不能继续。

通常,如果应用程序不是在fork()之后立即调用exec(),
就有必要在fork()被替换成vfork()之前做仔细的检查。

exec函数

(1)exec函数说明

fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。

(2)在Linux中使用exec函数族主要有以下两种情况

当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何exec 函数族让自己重生。

如果一个进程想执行另一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec函数使子进程重生。
(3)exec函数族语法

实际上,在Linux中并没有exec函数,而是有6个以exec开头的函数族,下表列举了exec函数族的6个成员函数的语法。

所需头文件

#include <unistd.h>

函数说明

执行文件

函数原型

int execl(const char *pathname, const char *arg, …)

int execv(const char *pathname, char *const argv[])

int execle(const char *pathname, const char *arg, …, char *const envp[])

int execve(const char *pathname, char *const argv[], char *const envp[])

int execlp(const char *filename, const char *arg, …)

int execvp(const char *filename, char *const argv[])

函数返回值

成功:函数不会返回

出错:返回-1,失败原因记录在error中

这6 个函数在函数名和使用语法的规则上都有细微的区别,下面就可执行文件查找方式、参数表传递方式及环境变量这几个方面进行比较说明。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值