zoukankan      html  css  js  c++  java
  • Apue.2e Chapter8 Process Control

    8~11章主要讲进程相关的内容。

    进程标示符(PID),0是调度进程,1通常是init进程,2一般是页守护进程(pagedaemon),负责虚拟内存的分页操作。

    #include <unistd.h>

    pid_t getpid(void);

    pid_t getppid(void);    //parent pid

    uid_t getuid(void);

    uid_t geteuid(void);

    gid_t getgid(void);

    gid_t getegid(void);

    区分实际ID,有效ID,保存的ID。

    fork函数

    pid_t fork();

    子进程是父进程的副本,获得父进程空间的数据空间、stack、heap的副本,共享.text段。写时复制。

    Linux:clone,fork的泛型,可以控制父子进程共享的部分;

    父进程所有打开的文件描述符会被复制到子进程中,相同的描述符之间共享同一个文件表项;

    父子进程之间有大量属性被继承,除了:进程ID、文件锁、闹钟、信号集。

    fork后如果立刻执行新程序,也可以调用spawn;

    废弃接口:vfork,建立子进程并阻塞父进程知道exit或exec被调用,父子进程之间共享数据段(子进程在父进程地址空间运行);

    exit函数

    _Exit(ISO)和_exit(Posix.1)在UNIX下同义,exit会执行全局的flush。

    退出状态和终止状态:后者指的是进程结束状态,前者指的是传递给exit函数的参数或main的返回值;

    如果父进程在子进程结束前终止,子进程将被init进程认领,其父进程自动转为init进程;

    如果一个子进程已经结束,其父进程未做好善后处理,这样的进程就是所谓的僵尸进程(zombie,用ps显示为z);

    wait和waitpid

    #include <sys/wait.h>

    pid_t wait(int *statloc);

    pid_t waitpid(pid_t pid, int *statloc, int options);

    wait的功能简单:等待任意子进程,阻塞父进程,等待到后返回子进程pid;

    waitpid可以指定等待进程的pid(pid>0),或任意子进程(pid=-1),或指定组id(pid<-1),或要求组ID=调用进程组id;

    options有些选项可以扩展功能,包括作业支持和非阻塞等待(WNOHANG,返回0)。

    statloc如果非0,可以存放子进程终止状态,然后使用四个互斥的宏来解析这些状态,包括:

    WIFEXITED:正常终止,可以通过WEXITSTATUS来获得终止返回值;

    WIFSIGNALED:异常终止,可执行WTERMSIG取使之终止的信号编号;有些实现可以用WCOREDUMP取得核心转储文件;

    WIFSTOPPED:若为当前暂停子进程返回的状态,则为真;可使用WSTOPSIG取使子进程暂停的信号编号;

    WIFCONTINUED:若在作业控制暂停后已经继续的子进程返回了状态,则为真。

    waitid //SUS

    #include <sys/wait.h>

    int waited(idtype_t idtype,id_t id, siginfo_t *infop, int options);

    idtype可取:

    P_PID:等待一个特定的进程;

    P_PGID:等待一个特定进程组中的任一子进程;id包含要等待子进程的进程组ID;

    P_ALL:等待任一子进程,忽略id;

    options的参数与waitpid类似,包括作业控制、非阻塞等待等功能;

    infop参数时指向siginfo的指针,该结构包含了有关引起子进程状态改变的生成信号的详细信息。

    wait3和wait4

    非posix,多一个参数,返回由终止进程及其所有子进程使用的资源汇总。

    竞争条件

    当多个进程以不确定的顺序处理共享数据,这就发生了竞争条件。避免的方法是使用轮询(耗时)或使用信号进行异步编程。

    这里的例程用到了后面signal部分的知识。

    exec函数

    共6个exec系的函数,包括execl, execlp, execle, execv, execvp, execve,其中l表示list,p表示path,v表示vector,e表示environment,以p结尾的函数第一个参量都是filename,如果实参中不包括/,那么系统会在PATH中进行搜索该文件名;l和v是两种不同传递字符串参数的方法;有e的还有再传递环境变量(否则会继承父进程的);

    参数表的长度有一个限制,如果超出长度,可以使用xargs来拆分参数;

    exec系不会改变子进程的ID和一系列属性,对于文件的处理和FD_CLOEXEC标志有关,目录流一定会被关闭;在很多UNIX实现中,这6个函数只有execve是system call,其余都是library function

    更改用户ID和组ID

    #include <unistd.h>

    int setuid(uid_t uid);

    int setgid(gid_t gid);

    su:real id,enable id和saved id都改为uid;

    非su,uid=real id或saved id,此时设置enable id=uid;

    非su,且不满足上述条件,errno=EPERM,返回-1;saved id需要_POSIX_SAVED_IDS为真;

    如果没有setuid,exec系不会改变文件的enable id;saved id是exec函数复制enable id而来;

    int setreuid(uid_t ruid, uid_t euid);

    int setregid(gid_t rgid, gid_t egid);

    交换real id和enable id。

    int seteuid(uid_t uid);

    int setegid(gid_t gid);

    更改enable id。

    解释器文件

    就是某些脚本文件,可以指定解释。

    第一行的形式必须是#!pathname [optional-argument]

    pathname指定解释器[绝对]路径,后面跟的是可选参数。一般有长度限制

    解释器文件一般用来写其他(除了/bin/sh)之外的shell脚本文件。

    system函数

    标准库函数。如果实参传递NULL,则返回非0表示system函数可用;

    在Unix中,system本质是fork+exec+waitpid;

    如果fork失败,或waitpid返回除EINTER之外的出错,返回-1,errno改变;

    如果exec失败,返回值同shell执行 exit(127);

    否则所有3个函数都执行成功,返回shell的终止状态(即waitpid中的statloc);

    system函数的优势:集成了各种错误处理和信号机制;

    注意setuid或者setgid的程序绝不应该调用system函数,否则会引起安全方面的漏洞。

    进程会计

    某个Unix的选项功能,激活后可以让内核处理记录进程的某些统计数据,可以将之重定向到文件,进行日志记录。

    用户标识

    获得用户登录名:

    char *getlogin(void);

    然后就可以通过该函数的返回值调用getpwnam等函数取得其他所需信息。

    进程时间

    #include <sys/times.h>

    clock_t times(struct tms *buf);

    填充tms结构的元素包括用户cpu时间、系统cpu时间和已结束的子进程相关时间;

    返回墙上时钟时间。

  • 相关阅读:
    2013第38周日Java文件上传下载收集思考
    2013年第38周六这一刻,行动
    2013年9月20日突然的焦虑
    2013中秋
    2013第38周三
    2013年第38周二
    2013第38周一电话开会邮件
    for循环中一个不容小觑的问题
    NPOI 创建Excel,数据读取与写入
    linux下mysql数据的导出和导入
  • 原文地址:https://www.cnblogs.com/livewithnorest/p/2878911.html
Copyright © 2011-2022 走看看