• 进程学习笔记


    进程:

    什么是进程?为什么要学进程?

    阻塞的概念…………………….标准IO流中等待获取信息,,,,等待就是阻塞!

    嵌入式设备---------数据的采集

    如何创建进程??

    程序:是静态的,程序的运行-à进程。

    进程----它是一个程序的实例;  进程--à①---à②<-----线程--à调度  

    ①资源的分配      进程是程序执行和资源分配的最小单位

    ②进程描述符(tast_struct)  结构体----用来描述一个进程

    sizeof(tast_struct) -----1.7k

    ③线程   (内核调度的最小单位)  内核怎么执行它?  current 指向当前需要执行的进程。。。。。

    ④调度

    进程                                       程序

    文本段 text                                二进制指令集的结合(文本段)

    数据段data                                文本段text------数据段(全局段)

    堆栈段stack(局部变量,回调关系)文本段—自读数据,而数据段为可读写数据

    数据段:存放的是全局变量、常数以及动态分配数据分配的空间(malloc)

    文本段:存放程序中的代码。

    堆栈段:存放的是函数返回的地址,函数的参数以及程序中的局部变量。

    进程ID

    task_struct 中存在一个进程号PID,为用户提供找到tast_struct这结构体,另外还有一个parent指向tast_struct,不能给用户和直接操作,所以又提供另一PPID父进程号。。。。

    ps  -ef  查看进程号

    pid = getpid()对于每个进程来说都是唯一的。。。    ppid = getppid()  

    init   一号进程,这个一号进程能够获得什么东西呢???孤儿进程的回收站

    init是内核启动到最后阶段,自动执行的。。。。。init创建一个tast_struct去执行其它程序。。。

    linux系统中的进程类型:

    ① 交互式进程:由shell控制和运行的。。

    ②批量出路进程   很少使用

    ③守护进程:该程序在后台运行,其次它与所有终端都无关,一般在linux启动时开始执行,系统关闭的时候才结束。。。

    进程的运行状态:

    ①运行态:此时进程或者在运行或在准备运行

    ②等待态:

     可中断------不可中断

    ③停止态:进程终止。。。。。。debug时。。。。

    死亡态:也叫僵尸态。子进程退出,但是父进程没退出,此时的子进程就是僵尸态。。。子进程的状态不会被系统回收,它需要父进程回收。。。注意:父进程必须及时注意回收子进程,以免内存泄露

    进程的模式:

    ①3G 大小的 用户空间   用户模式  只能通过系统调用(system  call)来操作内核

    ②1G 大小的 内核空间   内核模式   物理地址映射到虚拟空间的部分

    6.32         位操作系统 拥有4G寻址空间

    7.进程的一些命令:

    ps  查看系统中的进程  -aux  显示详细信息   -ef 

    top  和 资源管理器相似。。。。。一直刷新显示不同的状态

    注意:pstop  依赖与/proc目录(proc文件系统),因为/proc是挂载点,掉电丢失。。。。/proc中每个数字都为一个进程号

     

    nice (需要权限)按用户指定某种优先级来运行进程   nice  --20 ./a.out  &     %100独占CPU(优先级的概念:高优先级的任务分配更多的时间片。。。。    抢占 :重新分配时间片  )

    renice 改变正在运行进程的优先级   renice  -19  PID号

    kill   向一个进程发送一个信号    kill  -l 可看到这些信号  

    例如:kill  -9  PID号   向PID号的进程发送9这一信号(SIGKILL)

    history  | grep  renice  查看历史renice信息

     bg  将挂起(ctrl + z)的进程放到后台执行

     fg   将最后挂起的进程重新放到前台运行

    8. 创建一个进程:  目的,让两个人进程间有血缘关系,执行同一程序中的不同的代码部分。。。

    fork() 没有参数。。。

    注意:返回值,{-1  失败, 0  或者 > 0  成功}

    调用一个fork()----即创建了2个进程。。。。   clone出一个父进程的子进程,即2相同的进程,执行相同的代码。fork执行的过程中即已经变为2个进程,同时向父进程返回一个大于0的号,向子进程返回一个0.。。。。。。。(父进程为什么要返回 > 0? 因为父进程有多个儿子。。。)

    if(pid = = fork()<0)   理论上子进程先执行

           exit -1;

    if (pid  >  0)

           ppid; // 父进程

    else if (pid == 0)

        pid; // 子进程

    9.vfork()与fork()的不同之处:数据共享----执行顺序------退出

    vfork不拷贝父进程的任何资源,但和父进程共享资源。。。。。

    vfork之后父进程停止,而先执行子进程,子进程执行完成后且调用exec或者exit(),然后才执行父进程。。。

    即用vfork的主要目的是调用exec

    子进程必须调用exec 或者exit0)。。如果没有,则程序执行出现异常

     

    当今的fork是写拷贝技术。。。。。。。。写拷贝技术????当数据需要用时才拷贝,否则不拷贝。。这样的好处就是,避免了vfork的数据共享,也避免了fork的全拷贝。。。。。。

    10.exec函数族(有6个)

    shell脚本--------C语言中 

    函数的作用:把当前进程作为一个容器,然后将另外一个程序的内容填充。。。。。所以,exec后的程序将不能执行。。。

    注意:在使用exec函数族时,一定要加上错误判断语句。。。。。

    if execl”/bin/ls”,”ls”,”-l”,NULL< 0  //  NULL是一个类似哨兵,必须有这个参数

    {

           perror(“execl\n”);

    return -1;

    }

    11.完善man帮助包 。。。。有些man不出来

    sudo  apt-get  install  manpages-posix-dev

     

    12.exit(status)  #include<stdlib.h> 和 _exit(status)   #include <unistd.h>

    status是一个整型的参数,可以利用这个参数传递进程结束的状态。通常0表示正常结束;其他的数值表示出现错误。。。。

     exit和_exit()的区别:

    _exit()函数直接使进程停止运行,清除其使用的内存空间,并销毁其再内核中的各种数据结构;

    exit()函数则在这些基础上作了包装,在调用exit系统之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,即“清理I/O缓冲”。。。注意换行‘\n’也会引起I/O的清理工作。。。。。

    使用_exit退出,上一语句必须有’\n’换行符,才能够打印出语句。。。。

    13.wait和waitpid

    wait函数:只能父进程调用。。。。回收子进程的状态

    waitpid 主要功能:回收子进程的状态。。。。   wait  是waitpid的一个特例。。。。。。

    pid_t  waitpid(pid,status,options)

    参数:pid > 0,等待进程ID等于pid的子进程(指定ID)

          pid = -1 等待任意一个子进程 (wait == waitpid(-1,status,0))

          pid = 0 

          pid < -1

          WNOHANG:

          WUNHACED:

    与进程相关的概念:

    会话:每个用户登录一次,则开打一个会话

    进程组:在终端上执行,则产生一个进程组

    进程:

    14.守护进程 dacmon  主要运用在网络服务中使用

    一般是一些服务,常在系统启动时开始运行,系统关闭时终止。。

    一般运行在后台,脱离终端,它不属于

    ps  -ef 查看。。。。名字后面带个d,都是守护进程

    创建守护进程的步骤:

    创建子进程,父进程退出

    (第一步结束之后,子进程就在形式上与控制终端脱离,又由于负进程已经先于子进程退出,子进程变成了孤儿进程)

    pid = fork();

    if (pid >0)

       exit(0);

    在子进程中创建新的回话

    进程组是一个或者个进程的集合,进程组由进程组ID来唯一标识。没给进程组都有一个组长进程,进程组ID组长进程的进程号)

       (会话组是一个或者多个进程组的集合。。。在子进程中创建新的会话,)

    setsid();// 创建一个新的会话,并使得当前进程称为新会话组的组长。

           //setsid函数能够使进程完全独立出来,从而脱离所有其他进程的控制。。。。。

    改变工作的目录为目录

    chdir(“/”);

    重设文件权限掩码

    umask(0);

    关闭文件描述符

    (新的进程会从父进程那里继承所有已经打开的文件。。。再创建完成新的会话之后,守护进程已经脱离任何控制终端,应当关闭用不到的文件)

    close(fd); 

    实验例程:

    查看系统环境变量

    #include <stdio.h>

    int main(int argc, char **argv, char **envp)

    {

      int i = 0;

      while(envp[i]  != NULL)

      {

          printf("%s\n", envp[i]);

             i++;

         }

        return 0;

    }

       

  • 相关阅读:
    5.0、Android Studio调试你的应用
    4.4、Android Studio在命令行运行Gradle
    4.3、Android Studio突破64K方法限制
    4.2、Android Studio压缩你的代码和资源
    4.1、Android Stuido配置你的Build Variant
    【java多线程系列】java中的volatile的内存语义
    【java多线程系列】java内存模型与指令重排序
    4.0、Android Studio配置你的构建
    HashMap
    zk常用命令
  • 原文地址:https://www.cnblogs.com/zhou2011/p/2310004.html
Copyright © 2020-2023  润新知