UNIX高级编程-进程控制

第8章进程控制

8.1 进程标识符

Pid: 0(调度进程,swapper)

Pid: 1(初始化进程,init),自举内核后启动UNIX系统,通常读与系统相关的初始化文件,并将系统引导至一个状态

Pid_t getpid(void);   //获得当前进程id

Pid_t getppid(void);//获得父进程id

Uid_t getuid(void);  //获得当前用户id

Uid_t geteuid(void);

Gid_t getgid(void);//获得当前组id

Git_t getgid(void);

 

8.2 fork()函数

Pid_t fork(void);//用于创建一个新进程(子进程),调用一次,返回两次)子进程的返回值为0,父进程的返回值为新子进程的进程ID

子进程是父进程的副本,资源相同但不共享

COW(Copy-On-Write,写时拷贝),当父进程或者子进程企图修改共享区域时,,内核只需修改区域的那块内存用于制作一个副本,即子进程的修改不会影响父进程,父子进程随机交叉执行

网络服务进程中常在fork()之后由父子进程关闭不需要使用的文件描述符(父子进程分别执行不同的程序段)

父进程等待子进程完成,无需对其描述符进行任何处理

父进程与子进程的相同属性,包括有效用户ID,有效用户组ID,实际用户ID,实际用户组ID,,设置用户ID,设置组ID,根目录,当前工作目录等等。

父进程与子进程的区别:pid,父进程ID等等P175

fork()的两种用法:

(1)    父进程等待服务请求到达,父进程调用fork()创建子进程处理此请求,父进程则继续等待下一个服务请求

(2)    一个进程要执行一个不同程序,子进程从fork()返回后立即调用exec();

 

8..3vfork()函数

确保子进程先运行,在调用exec或者exit之后父进程才可能调度运行;子进程在父进程的地址空间执行

 

8.4 exit函数

进程的5种正常终止方式

(1)    在main()函数内执行return语句

(2)    调用exit()函数,调用各种终止处理程序。关闭所有标准IO流

(3)    调用_exit或_Exit函数,无需运行终止处理程序或信号处理程序而终止的方法

(4)    进程的最后一个线程在启动例程执行返回语句

(5)    进程的最后一个线程调用pthread_exit()函数

无论程序如何终止,均会执行内核中的关闭所有打开描述符,释放所使用的存储器

当一个进程终止时,内核逐一检查所有活动进程,以判断是否是正要终止进程的子进程,人如果是则将该进程的父进程ID更改为1

如果子进程在父进程之前终止,当终止进程的父进程调用wait或者waitpid可以获取这些信息,内核便可以释放终止进程所有的存储区,关闭其打开的全部文件。

僵死进程:父进程未对子进程进行妥善的处理

 

8.6wait和waitpid函数

(1)如果所有的子进程均还在运行,则阻塞该进程

(2)如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态(3)如果并无子进程,则出错

Pid_t wait(int *statloc);

Pid_t waitpid(pid_t pid,int *staloc,intoptions);

Waitpid()与wait()相比的三大区别:

1)waitpid看可以根据pid传参数从而决定等待的特定子线程

2)waitpid提供了一个非阻塞的版本

3))waitpid支持作业控制

 

8,7waitid函数

Int waited(idtype_t idtype,id_tid,siginfo_t *infop,int options);

Idtype:P_PID(等待特定的子进程),P_PGID(等待特定进程组的任意子进程)P_ALL(任意的子进程)

Options:关注哪些状态改变

Infop:引起子进程状态改变的生成信号

 

8.8wait3和wait4

Pid_t wait3(int *statloc,int options,structrusage *rusage);

Pid_t wait4(pid_t pid,int *statloc,intoptions,struct rusage *rusage):

Resage:要求内核返回终止进程及其所有子进程的全部资源汇总

 

8.9 竞争条件

通过信号量控制父进程和子进程的执行顺序从而避免竞争WAIT_PARENT(),TELL_CHILD(父进程id),TELL_PARENT(getppid()),WAIT_CHILD()

 

8.10exec函数

Exec()实质上是执行了另外一段程序

 

8.11更改用户ID和组ID

最小特权模型:设计应用程序时,应当只具有为完成给定任务所需的最小特权

Int setuid(uid_t uid);  //设置实际用户ID,有效用户ID

1) 如果进程具有超级用户特权,则setuid函数将实际用户ID,有效用户ID,设置用户ID设置为uid

2) 如果进程不具有超级用户特权,但uid、等于实际用户ID和设置用户ID,则将有效用户ID设置为uid

3) 只有超级用户进程可以更新实际用户ID

4) 仅对当前程序文件设置了设置用户ID时,exec()函数才会设置有效用户ID

5) 保存的设置用户ID是由exec()复制有效用户ID而得来的

Int setgid(gid_t gid);  //设置实际组ID,有效组ID

 

8.12解释器文件、

!pathname [optional-argument] pathname(绝对路径)实际上执行的是pathname对应的文件

 

8.13 system函数

Int system(const char *cmdstring);//能进行所需的各种出错处理以及各种信号处理

 

8.14进程会计

类似于日志文件,使用accton命令启动会计处理,每当有进程终止时,会将该进程的命令名,CPU执行时间,用户ID,用户组ID,启动时间等等信息记录下来,

会计记录的结构是struct acct{

Char ac_flag;  //进程完成的事件

Char ac_stat;  //进程终止状态

Uid_t ac_uid; //进程的用户ID

Gid_t ac_gid; //进程的组ID

Dev_t ac_tty; //进程的控制终端

Time_t ac_btime;  //启动日历时间

Comp_t ac_utime;  //用户CPU时间

Comp_t ac_stime;  //系统CPU时间

Comp_t ac_etime;  //经过时间

Comp_t ac_men;//平均内存使用

Comp_t ac_io; //传输的字符数

Comp_t ac_rw; //读写的块数

Char ac_comm[8];//命令名

}

Fork()会新增会计记录

Execl()只会改变命令名

Abort()会产生信号SIGABRT,从而进行core转存

Kill()会产生SIGKILL信号,但只是终止该进程

 

8.15 用户标识

Char *getlogin(void);//获取登录名

 

8.16 进程时间

Clock_t times(struct tms *buf);  //获取进程时间

Struct tms{

Clock_t tms_utime; //用户CPU时间

Clock_t tms_stime;//系统CPU时间

Clock_t tms_cutime;//终止子进程的用户CPU时间

Clock_t tms_cstime; //终止子进程的系统CPU时间

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值