一、基础知识

1:进程。

  1,进程ID: 非负整数,具有唯一性。

    1)ID=0的进程:调度进程/交换进程。内核的一部分。不执行任何磁盘上的程序。

    2)ID=1的进程:init进程。

      1-自举结束时,由内核调用,且不会终止。

      2-用于读取与系统有关的初始化文件。并引导系统至一个状态。

      3-使用root权限运行,是所有孤儿进程的父进程。

    3)ID=2的进程:页守护进程。负责支持虚拟存储器系统的分页操作。

  2,僵死进程:已经终止,但其父进程尚未对其进行善后处理的进程。

  3,进程调度。

    1)UNIX系统只提供基于调度优先级的粗粒度的控制。

    2)调度策略和调度优先级由内核确定。

    3)进程可以通过调整nice值来降低优先级运行。(不可提升)

    4)只有特权进程允许提高优先级。(应该指root)

  4,父进程和子进程。

    1)父进程和子进程只共享正文段。其他仅为副本,仅在复制的此刻保持一致。linux中,增加函数clone。可以控制哪些部分共享,哪些部分不共享。

    2)每个进程都有一个父进程。子进程终止时,父进程得到通知并获取子进程的退出状态。

    3)通常进程的父进程是什么?用户进程?

    4)子进程的用途。

      1-父进程希望复制自己。例如:服务器中,等待客户端服务请求。请求到达,复制一份子进程执行请求。父进程继续等待请求。
      2-进程需要执行另外一个程序。此情况下,fork后将立即调用exec函数。

  5,进程组:多个进程的集合。

    1)每个进程组由一个组长进程。组长进程的ID就是进程组ID。

    2)进程组中的最后一个进程可以终止,也可以转移到另一个进程组。

    3)进程可以设置自己和子进程的进程组ID。但子进程调用exec后,就不能再通过父进程修改进程组ID了。

  6,会话:包含一个或多个进程组。

    1)会话ID为会话首进程ID。会话首进程称为 控制进程。

    2)一个会话可以有一个控制终端。(终端或伪终端设备)

    3)会话分为:一个前台进程组和多个后台进程组。

2:进程中的用户和用户组。

  1,进程中分为:实际用户/组,有效用户/组,设置用户/组。

    1)实际:进程执行用户。

    2)有效:决定进程访问权限。通常 实际== 有效

    3)设置:设置ID由exec函数保存。当有效时,则将设置ID变为有效ID。

    4)stat->st_mode中有两个特殊标志位(分别控制用户和组)。置位作用为:当执行此文件,进行的有效ID将便为该文件的所有者ID。(用户和组由不同位控制)

  2,设置ID可以间接获得其他用户权限。需要慎重使用。(例:用户更改自己的密码,口令文件为root所有。)

  3,非root权限的进程,写文件时,设置用户/组ID位会清除。

  4,新文件用户ID为:进程有效用户ID。

  5:新文件的组ID有两种情况(linux 3.2.0):

    1)所在目录的设置组ID置位时:和所在目录的组ID一样。

    2)所在目录的设置组ID未置位时:进程有效组ID。

3:进程启动和终止。

  1,启动:

    1)内核使程序执行的唯一方法时调用一个exec函数。

  2,正常终止:

    1)从main返回。

    2)从exit, _exit, _Exit函数调用。

    3)最后一个线程: 从启动例程返回 或 调用pthread_exit.

  3,异常终止。

    1)调用abort函数。

    2)接收到一个信号(终止相关)

    3)最后一个线程对取消请求做出响应。

3:C程序的储存空间布局。下列顺序由高地址到低地址排序。

  1,命令行参数和环境变量。

  2,栈(stack):往低地址方向增长。保存:自动(临时)变量 和 函数调用相关信息(形参,返回地址等)

  3,堆(head):往高地址方向增长用于动态储存分配。(例如:new,malloc等)

  4,未初始化数据:称之为bss段。保存了已经未初始化的全局/静态变量。

  5,初始化数据:保存了已经初始化的全局/静态变量。

  6,包含常量数据:如果不细分,也可以当作初始化数据的一部分。

  7,正文:CPU执行的机器指令保存部分。

低地址 正文(text) 常量数据(rodata) 初始化数据(data) 未初始化数据(bss) heap(堆)  -->       unused    <--  stack(栈) environment 高地址

  8,子进程创建时,拥有父进程其他一切数据的副本,但只有exec程序执行后,才拥有栈和堆。

4:守护进程。

  1,基本概念。

    1)生存周期长的进程。

    2)通常在后台运行。

    3)使用 ps -axj可以显示进程。守护进程的名字出现在方括号[ ] 中。

    4)需要在进程上下文执行工作,单不被用户层进程上下文调用的内核组件,通常都有自己的守护进程。

    5)守护进程通常以root权限运行。

  2,产生日志消息的方式。

    1)内核例程调用log函数。

    2)守护进程调用syslog函数产生。

    3)将日志消息发送向UDP端口514。(网络用户也可以使用)

  4,守护进程遵循下列通用惯例。

    1)如果守护进程使用锁文件。一般储存在/var/run目录下。锁文件名为name.pid

    2)如支持配置选项,目录为 /etc 名字为 name.conf

    3)可以使用命令行启动,通常由系统初始化脚本启动

    4)如果守护进程由配置文件,那启动时会读取该文件。之后一般不会再查看。如果修改配置,需要重启守护进程。

二、相关函数。

 退出函数。
  void exit( int status )
  void _Exit( int status )
  void _eixt( int status )
  // 1 stdlib.h 包含exit _Exit.unistd.h包含_exit
  // 2 参数status 将作为main函数的返回值返回。
  // 3 只有exit函数而没有return返回时,部分编译器可能会出现报错或者警告
登记一个函数为终止处理函数。
  // 1 终止处理函数将由exit函数自动调用。
  // 2 注册顺序和调用顺序相反。
  // 3 可以用sysconf函数来查询最大终止程序数(最少支持32个)
  int atexit( void (*func)(void) );
内存分配函数。
  void *malloc( size_t size ); // 按大小分配内存。
  void *calloc( size_t nobj, size_t size ); // 按指定数量和指定长度的对象分配储存空间。
  void *realloc( void *ptr, size_t newsize ); //增加/减少以前分配区的长度。
  void free( void *ptr ); //释放内存。
  // 1 分配函数返回的指针一定要适当对齐。例:double必须在8的倍数地址单元处开始。
  // 2 由隐性的转换规则。如无,则默认返回为int。没有正确的转换类型可能导致隐性的系统错误。
环境变量函数
  int putenv( char *str ); // 参数形式:name=value。否则出错。
  int setenv( const char *name, const char *value, int rewrite ); // 参数rewrite 非零时,会强制写。否则,不会进行覆盖操作。
  int unsetenv( const char *name ); // 删除一个环境变量。
进程资源的设置和查询
  int getrlimit( int resource, struct rlimit *rlptr ); // 查询
  int setrlimit( int resource, const struct rlimit *rlptr ); // 设置(更改)
  // 1 软限制 <= 硬限制。
  // 2 任何进程都可以降低硬限制。此过程不可逆。
  // 3 root用户才可以增加硬限制。
  // 4 资源限制会影响到子进程。
查询 子进程终止状态 函数。
  pid_t wait( int *statloc );
  pid_t waitpid( pid_t pid, int *statloc, int options );
  // 1 参数pid:==-1 等待任一子进程,>0 等待与pid相同ID的子进程,==0 等待组ID等于调用进程组ID的任一子进程,<-1 等待组ID等于pid绝对值的任一子进程。
  int waitid( idtype_t idtype, id_t id, siginfo_t *infop, int options );
  pid_t wait3( int *statloc, int options, struct rusage *rusage );
  pid_t wait4( pid_t pid, int *statloc, int options, struct rusage *rusage );
  // 1 三种情况:无终止子进程,则阻塞。有子进程终止,并且有信号发出,则返回该子进程的终止状态。进程本身没有任何子进程,则返回出错。
  // 2 waitpid函数可以选择无终止子进程时,不阻塞
创建子进程
  pid_t fork(void);
  pid_t vfork(void);
  // 1 调用一次,返回两次。父进程返回子进程ID,子进程返回0。返回顺序,取决于执行顺序。
  // 2 可能的失败原因:超过可拥有的最大ID数 或 系统中进程数量过多(系统本身已经存在问题)
  // 3 vfork函数:保证子进程先运行。且必须先exec执行子进程。如不执行,则会在父进程栈中进行运行。
  // 4 尝试代码后,怀疑,从fork开始,就会有2个进程同时执行 fork 之后的代码。
启动函数。
  int execl( const char * pathname, const char *arg0, ...)
  int execv( const char * pathname, char *const argv[] )
  int execle( const char * pathname, const char *arg0, ...)
  int execve( const char * pathname, char *const argv[], char *const envp[] )
  int execlp( const char * pathname, const char *arg0, ...)
  int execvp( const char * pathname, char *const argv[] )
  int fexecve( int fd, char *const argv[], char *const envp[] )
  // 1 filename包含/ 则当作路径名。都则按照PATH环境变量,在各目录搜索可执行文件。
  // 2 PATH变量中包含目录表,用 : 隔开。例:PATH=/bin : /usr/bin
操作 进程 用户/组 ID
  int setuid( uid_t uid ); // 设置有效用户ID。如果有root权限,还可以更改实际用户。
  int setgid( gid_t gid ); // 设置有效组ID。如果有root权限,还可以更改实际组。
  int setreuid( uid_t ruid, uid_t euid ); // 交换实际用户和有效用户ID。
  int setregid( gid_t rgid, gid_t egid ); // 交换实际组和有效组ID。
  int seteuid( uid_t uid ); // 仅设置有效用户ID。
  int setegid( uid_t gid ); // 仅设置有效组ID。
  // 1 只有root用户才可以更改实际用户ID。
  // 2 普通用户不能进行权限以外的其他操作。
进程调度函数(优先级)
  int nice( int incr ); // 更改优先级,只能更改进程本身的优先级(拥有root权限除外)。
  int getpriority( int which, id_t who ); // 获得nice值
  int setpriority( int which, id_t who, int value ); // 设置nice值。
  // 1 nice值输入过大或过小,函数都会自动进行调整。
进程时间 结构体
  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时间,以及终止子进程时间
  }
进程组
  int setpgid( pid_t pid, pid_t pgid ); // 加入/创建一个进程组
  // 1 调用该函数后,进程和控制终端的联系会被切断。
  pid_t tcgetpgrp( int fd); // 得到进程进程组ID
  int tcsetpgrp( int fd, pid_t pgrpid ); // 设置前台进程组ID。
会话
  pid_t setsid( void ); // 建立一个新会话。
  pid_t tcgetsid( int fd ); // 会话首进程的进程组ID。
守护进程函数。
  void openlog( const char *ident, int option, int facility );
  void syslog( int priority, const char *format );
  void closelog( void );
  int setlogmask( int maskpri );

三、

最新文章

  1. javascript星级评分(多个)
  2. sudo 命令情景分析
  3. 获取tomcat下路径
  4. IOS开发-UIScrollView陷阱之----删除所有子view, 滚动条(indicator) 消失
  5. GCC、ARM-LINUX-GCC、ARM-ELF-GCC浅析
  6. js事件绑定细节说明
  7. 第二百五十三、四、五天 how can I 坚持
  8. cocos2dx3.1.1+cocosstudio+lua问题总结
  9. 虚拟机比较(wiki)
  10. aJax学习之Ajax工作原理
  11. 一个不应该犯的错octave
  12. 关于OMAPL138烧写程序的说明
  13. C语言--第四周作业
  14. Android实现横屏以及全屏的小技巧
  15. Python:黑板课爬虫闯关第三关
  16. X-pack 6.4.0 破解
  17. image_channel_data_type含义
  18. springboot在eclipse中运行使用开发配置,打包后运行使用生产环境默认配置
  19. java数据结构之二叉树的定义和递归实现
  20. Git 软件开发过程

热门文章

  1. 13年山东省赛 Mountain Subsequences(dp)
  2. (原)使用mkl计算特征值和特征向量
  3. zongjie
  4. GTW likes gt(BC 模拟 or 优先队列)
  5. Constructing Roads(1102 最小生成树 prim)
  6. wordpress教程之WP_Query()类
  7. SpringMVC原理+流程图
  8. 十五、命令(Command)模式--行为型模式(Behavioral Pattern)
  9. easy_install django==1.4.2_百度搜索
  10. [置顶] think in java interview番外篇-谈程序员如何修练英语