zoukankan      html  css  js  c++  java
  • linux ——process

    1、概念

    进程是具有独立功能的程序关于某个数据集合的一次运行活动,是系统进行资源管理的基本单位。

    (程序是存放在存储介质上的静态指令的集合,与进程最大的区别,程序是静态的,进程是动态的)

    2、用途

    进程是管理事务的基本单元:操作系统是通过进程去完成某个任务,管理事务,就好像,学校是通过班级管理事情,公司是通过部门去管理

    3、特点

    进程就运行的状态可分为三种状态,就绪态、运行态、阻塞态。

    运行态<==>就绪态<---阻塞态<----运行态

    4、用法

    ①创建进程

    #include <unistd.h>

    pid_t fork(void);

    pid_t vfork(void);

    fork与vfork的区别与共同点:

    区别:

    ①fork创建的进程父、子进程运行顺序不确定,而vfork创建的进程保证子进程先运行,子进程结束(调用exit或exec)运行父进程再运行

    ②fork创建的子进程完全是父进程的一个复制品,它从父进程处继承了整个地址空间,而vfork在调用exec或exit之前,它在父进程的地址空间运行,在exec之后子进程会有自己的进程空间

    ③vork可以实现父子进程之间简单的同步

    共同点:

    都可以创建一个新进程

    ②进程的资源回收

    #include <sys/types.h>

    #include <sys/wait.h>

    pid_t wait(int *status);

    等待子进程改变状态,如果子进程终止了,此函数会回收子进程的资源。调用wait函数的进程会挂起,直到它的一个子进程退出或受到一个不能被忽视的信号时才被唤醒。

    执行成功返回子进程的pid号,出错返回-1.

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

    等待子进程改变状态,如果子进程终止了,此函数会回收子进程的资源。

    pid>0 等待进程id等于pid的子进程;

    pid=-1;等待任一子进程,此时waitpid和wait作用一样

    pid<-1 等待指定进程组中的任何子进程,这个进程组的id等于pid的绝对值。

    ③进程的关闭

    #include <stdlib.h>

    void exit(int status);

    exit函数:结束进程执行
    #include <unistd.h>
    void exit(int value)
    参数:
        status:返回给父进程的参数(低8位有效)。
    _exit函数:结束进程执行
    #include <unistd.h>
    void _exit(int value)
    参数:
        status:返回给父进程的参数(低8位有效)。

    exec函数族,是由六个exec函数组成的。
    exec函数族提供了六种在进程中启动另一个程序的方法。
    exec函数族可以根据指定的文件名或目录名找到可执行文件。
    调用exec函数的进程并不创建新的进程,故调用exec前后,进程的进程号并不会改变,其执行的程序完全由新的程序替换,而新程序则从其main函数开始执行。

    #include <unistd.h>
    int execl(const char *pathname,           const char *arg0,…,NULL);
    int execlp(const char *filename,              const char *arg0,…,NULL);
    int execle(const char *pathname,           const char *arg0,…,NULL,              char *const envp[]);

    int execv(const char *pathname,                 char *const argv[]);
    int execvp(const char *filename,                              char *const argv[]);
    int execve(const char *pathname,            char *const argv[],             char *const envp[]);

    六个exec函数中只有execve是真正意义的系统调用(内核提供的接口),其它函数都是在此基础上经过封装的库函数。
    l(list):
      参数地址列表,以空指针结尾。
    参数地址列表
     char *arg0, char *arg1, ..., char *argn, NULL
    v(vector):
      存有各参数地址的指针数组的地址。
      使用时先构造一个指针数组,指针数组存各参数的地址,然后将该指针数组地址作为函数的参数。

    p(path)
      按PATH环境变量指定的目录搜索可执行文件。
      以p结尾的exec函数取文件名做为参数。当指定filename作为参数时,若filename中包含/,则将其视为路径名,并直接到指定的路径中执行程序。
    e(environment):
      存有环境变量字符串地址的指针数组的地址。execle和execve改变的是exec启动的程序的环境变量(新的环境变量完全由environment指定),其他四个函数启动的程序则使用默认系统环境变量。

    5、案例


    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <wait.h>

    void shell(void)
    {
     while(1)
     {
      char cmd_buf[200] = "";
      char *argv[20] = {NULL};
      int i = 0;
      
      getcwd(cmd_buf, sizeof(cmd_buf));//获取当前目录保存在字符数组当中。
      printf("[%s@ %s]$", getenv("USER"), 1+strrchr(cmd_buf, '/'));//打印提示符号。
      fgets(cmd_buf, sizeof(cmd_buf), stdin);//获取字符串
      cmd_buf[strlen(cmd_buf)-1] = '\0';   //把最后一位'\n'变成字符串结束标志'\0'
      
      if(cmd_buf[0] == '\0')
       continue;    //如果是输入回车的话,继续while循环
      
      argv[i] = cmd_buf;
      while((argv[i++]=strtok(argv[i]," "))!=NULL);   //字符串按空格切割  
      
      if(fork()==0)  //创建子进程  调用execvp运行外部命令。
      {
       printf("argv[0] = %s\n", argv[0]);
       execvp(argv[0],argv);  
       printf("command no found!\n");
       exit(1);
      }
      wait(NULL);  //父进程等待子进程结束。
     }
    }

    int main(int argc, char *argv[])
    {
     shell();
     return 0;
    }


     

  • 相关阅读:
    SQL多表联合查询(Access数据库表)
    分时间片计算包间费演示程序
    SQL2000下的三表查询
    小学生课外必读书目(推荐)
    Delphi下POS机控制钱箱,客显,打印机
    三个实用的SQL Server数据库字典SQL语句
    delphi中关于资源释放(Free/release/freeAndNil)的一点体会(转)
    Data mining (2)
    求二进制数中1的个数
    延参法师在同济
  • 原文地址:https://www.cnblogs.com/kunyashaw/p/3127307.html
Copyright © 2011-2022 走看看