• 第36天-进程 _1(2013.09.06)


      1.物理地址-------MMU------》虚拟地址----启动进程---->进程空间地址

      2.Uxworks  FreeRTOS  Ucos/2

      3. volatile(不优化)  register(尽量优化)

      4.每个进程在内核中都有一个进程控制块来维护相关的信息,  Linux内核的进程控制块是tast_struct结构体

      5.两个重要的系统调用 fork(刀叉, 民间的, 分叉) 和 exec(执行)

          fork的作用 :根据一个现有的进程复制出一个新进程, 原来的进程称为父进程,新的进程称为子进程

          例外 : 子进程PCB中的进程id和父进程是不同的

      6.exit 和 _exit函数用于终止一个进程

          函数原型 : #include <stdlib.h>    void exit(int status);

                #include <unistd.h>    void _exit(int status);

          区别 :exit是标准C的库函数,负责完成标准C的其他库函数留下的清理工作。

              _exit是UNIX系统函数,是exit系统调用的包装,调用_exit函数时直接进入内核终止掉当前进程,释放分配的内存,关闭文件描述符, 不需要做用户空间的清理工作。

          扩展 : exit在做完清理工作后最终也是调用_exit终止当前进程的

      7.异常终止 :进程收到一个信号,然后内核把进程强行终止掉了, 进程并么有执行 _exit系统调用,也没有退出状态。(例如: Ctrl-C 或着Kill命令终止一个进程)

      8.可以使用echo 命令查看这个环境变量的值。

      9.如果给出name要在环境变量表中查找它对应的value, 可以用getenv函数

          函数原型 : #include <stdlib.h>  char *getenv(const char *name);

          返回值 : getenv的返回值是指向value的指针, 若未找到则为NULL 

      10. 修改环境变量的函数 :

          函数原型 : int setenv(const char *name, const char *value, int rewrite);

                void unsetenv(const char *name);

          putenv 和 setenv 函数若成功返回为0, 若出错返回非0

          setenv将环境变量name的值设置为value, 如果已存在环境变量name. 那么

                  若rewirite非0, 则覆盖原来的定义

                  若rewrite为0, 则不覆盖原来的定义, 也不返回错误

          unsetenv 删除name的定义。 即使name么有定义也不返回错误。

      11. 可剥夺型内核和不可剥夺型内核

      12.fork函数

           函数原型 : #include <sys/types.h>  #include <unistd.h>    pid_t fork(void)

           返回值 : 调用失败返回-1. 调用成功有两个返回值(pid == 0)执行子进程,(pid > 0)执行父进程

           当父进程结束,程序直接返回。

           可以使用usleep(0)在两个进程间故意切换

           fork函数的特点 : 调用一次 , 返回两次

           注意: fork在子进程中返回0, 子进程仍可以调用getpid函数得到自己的进程id, 也可以调用getppid函数得到父进程的id。在父进程中可以用getpid函数得到自己的进程id,然而想要得到子进程的id,只有将fork的返回值记录下来, 别无它法。

           fork的另一个特性 : 所有有父进程打开的描述符都被复制到子进程中。(即file结构体的引用计数要增加)

           gdb调式: 

                set follow-fork-mode child 命令设置gdb在fork之后跟踪子进程

                set follow-fork-mode parent 跟踪父进程。 

      13.exec函数  (Executive)执行

          提示: 调用exec前后該进程的id并未改变

          函数原型: #include <unistd.h>

              (重点)int execvp(const char *file, char *const argv[]);

                  int execl(const char *path, const char *arg, ...);

                  int execlp(const char *file, const char *arg, ...);

                  int execle(const char *path, const char *arg, ..., char *const envp[]);

                  int execv(const char *path, char *const argv[]);

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

          补充: 最少有两个指针, argv最后一个为 NULL

          扩展 : exec函数只有出错的返回值而没有成功的返回值,,出错返回-1

      14.僵尸进程: 如果一个进程已经终止, 但是它的父进程尚未调用wait或waitpid对它进行清理, 这时的状态称为僵尸进程

      15.如果一个父进程终止,而它的子进程还存在,则这些子进程的父进程改为init进程

            init进程: 一个特殊进程, 通常程序文件/sbin/init 进程id是1,在系统启动时负责启动各种系统服务, 之后就负责清理子进程, 只要有子进程终止, init就会调用wait函数清理它

          函数原型: #include <sys/types.h>  #include <sys/wait.h>

                pid_t wait(int *status);

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

           返回值 : 如果调用成功返回子进程id,调用失败返回-1

          父进程调用wait或waitpid时可能会: 

                      阻塞(如果它的所有子进程都还在运行)

                      带子进程的终止信息立即返回(如果一个子进程已终止,正等待父进程读取其终止信息)

                      出错立即返回(如果它么有子进程)

          这两个函数的区别 : 

                如果父进程的所有子进程都还在运行,调用wait将使父进程阻塞,而调用waitpid时如果在options参数中指定WNOHANG可以使父进程不阻塞而立即返回0

                wait等待第一个终止的子进程,而waitpid可一个通过pid参数指定等待哪一个子进程

          wait函数作用 ; 

                使用wait和waitpid可以获得子进程的终止信息。

                可以使父进程阻塞等待子进程终止,起到进程间同步的作用

                清理子进程

        扩展 ; 低字节判断信号, 高字节判断退出状态

      英语 ; abnormally(异常)    Executive(执行)

  • 相关阅读:
    随机性的控制
    856. 括号的分数
    376. 摆动序列(贪心算法)
    XGBoost 安装方法
    1405. 最长快乐字符串(贪心算法)
    1296. 划分数组为连续数字的集合(贪心算法)
    1353. 最多可以参加的会议数目(贪心算法)
    435. 无重叠区间(贪心算法)
    Array-数组-数据结构
    认识Redis和安装
  • 原文地址:https://www.cnblogs.com/cxw825873709/p/3309139.html
Copyright © 2020-2023  润新知