zoukankan      html  css  js  c++  java
  • 20191324读书笔记6

    第三章 Unix/linux进程管理

    • 多任务处理指的是同时进行几项独立活动的能力
    • 进程:在操作系统中,任务也称为进程,执行映像定义为包含代码、数据和堆栈的存储区,进程就是对映像的执行。
    • PROC结构体:在操作系统知识中我们学习过,进程的状态用一个独特的数据结构表示,叫做进程控制块(PCB)。在Liunx中也可以称为PROC结构体。PROC结构体包含某个进程的所有信息。
    点击查看PROC结构体
    typedef struct proc{
        struct proc *next;    
        int *ksp;            
        int pid;            
        int status;           
        int priority;         
        int  kstack [SSIZE];  
    }PROC;
    

    多任务处理系统

    • type.h文件定义了系统常熟和表示进程的简单PROC结构体
    点击查看代码
    /*********** type.h file ************/
    #define NPROC   9
    #define SSIZE 1024
    // PROC status
    #define FREE    0
    #define READY   1
    #define SLEEP   2
    #define ZOMBIE  3
    typedef struct proc{
        struct proc *next;
        int *ksp;
        int pid;
        int status;
        int priority;
        int  kstack [SSIZE];
    }PROC;
    
    • ts.s文件在32位GCC汇编代码中可实现进程上下文切换
    点击查看代码
    #-------------- ts.s file ----------------
           .globl running,scheduler, tswitch
    tSwitch:
    SAVE:   pushl %eax :
            pushl %ebx
            pushl %ecx
            pushl %edx
            pushl %ebp
            pushl %esi
            pushl %edi
            pushf1
            movl   running, Sebx
            mov1   # esp,4(%ebx)
    FIND:   call  scheduler
    RESUME: movl    running,8ebx
            movl    4(%ebx),%esp
            popf1
            popl %edi
            popl %esi
            popl %ebp
            popl %edx
            popl %ecx
            popl %ebx
            popl %eax
            ret
    # stack contents=|retPC|eax|ebx|ecx|edx|ebp|esi|edi|eflag|
    #                  -1   -2  -3  -4  -5  -6  -7  -8   -9
    
    • queue.c文件可实现队列和链表操作函数。
    点击查看代码
    /******************************* queue.c file *******************************/
    int enqueue(PROC **queue,PROC *p)
    {
        PROC *q = *queue;
        if(q == 0 || p->priority> q->priority){
            *queue = p;
            p->next = q;
        }
        else{
            while(g->next && p->priority <= q->next->priority)
                q = q->next;
            p->next = q->next;
            q->next = p;
        }
    }
    PROC *dequeue (PROC **queue)
    {
        PROC *p = *queue;
        if (p)
            *queue =(*queue)->next;
        return p;
    }
    int printList(char *name,PROC *p)
    {
        printf("%s = ",name);
        while(p){
            printf("[8d %d]->",p->pid,p->priority);
            p = p->next;
        }
        printf("NULL
    ");
    }
    
    • enqueue()函数按优先级将PROC输入队列中。在优先级队列中,具有相同优先级的进程按照FIFO的顺序排序。
    • dequeue()函数可返回从队列或链表中删除的第一个元素。
    • printList()函数可打印链表元素。
    • t.c文件定义MT系统数据结构、系统初始化代码和进程管理函数
    • 睡眠模式:当进程需要某些当前没有的东西的时候,就会进入休眠状态。
    • 唤醒操作:调用kwakeup()就可以唤醒一个进程。此时,正在休眠的一个程序得到了需要的资源,继续执行其操作。
    • 进程终止:进程完成后,就会终止或死亡。进程会以两种方式终止:1)正常终止:进程自行调用结束函数exit(value)进行终止。2)异常终止:进程因为某个信号而异常终止。终止时,都会调用kexit()。

    进程管理中的系统调用

    • fork:在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。
      通过fork返回的值来判断当前进程是子进程还是父进程。
    • exec:用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。
      因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用一个全新的程序替换了当前进程的正文、数据、堆和栈段。

    SHELL:指定将解释任何用户命令的sh。
    TERM:指定运行sh时要模拟的终端类型。
    USER:当前登录用户。
    PATH:系统在查找命令时将检查的目录列表。
    HOME:用户的主目录。在 Linux 中,所有用户主目录都在/home中。

    环境变量

    各环境变量定义为:关键字=字符串

    点击查看代码
    *#include <unistd.h>*
    *int execl( const char *pathname, const char *arg0, ... /* (char *)0 */ );*
    *int execv( const char *pathname, char *const argv[] );*
    *int execle( const char *pathname, const char *arg0, ... /* (char *)0, char *const envp[] */ );*
    *int execve( const char *pathname, char *const argv[], char *const envp[] );*
    *int execlp( const char *filename, const char *arg0, ... /* (char *)0 */ );*
    *int execvp( const char *filename, char *const argv[] );*
    

    I/O重定向

    • sh进程有三个用于终端I/O的文件流:stdin(标准输入)、stdout(标准输出)、stderr(标准错误)。其文件描述符分别对应0、1、2。

    管道 |

    • 管道是用于进程交换数据的单向进程件通信通道。管道有一个读取端和一个写入端。
    • 管道命令处理:在Unix/Linux中,命令行cmd1 | cmd2,sh将通过一个进程运行cmd1,并通过另一个进程运行cmd2,他们通过一个管道连接在一起,因此cmd1的输出变为cmd2的输入
    • 命令管道:命令管道又叫FIFO。在sh中,通过mknod命令创建一个命令管道:
      mknod mypipe p
      或在c语言中发出mknod()系统调用
      int r = mknod("mypipe",s_IFIFP,0);
      进程可像访问普通文件一样发个文命名管道。

    实践

    fork.c

    运行结果

  • 相关阅读:
    laravel-excel maatwebsite/excel 新版中文文档
    laravel-excel.com官网英文站
    composer查看镜像地址
    Navicat Premium 通过ssh 连接服务器
    Centos7 yum 出现could not retrieve mirrorlist 最终解决方案
    php 获取随机字符串算法
    apache 配置多域名访问的方法
    laravel 配置多域名最简单的方法
    es6知识点
    如何判断浏览器为ie10以上
  • 原文地址:https://www.cnblogs.com/pxmxxr/p/15451601.html
Copyright © 2011-2022 走看看