IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux || 进程 -> 正文阅读

[系统运维]Linux || 进程

虚拟地址、内存、进程管理、状态模式(tcp三次握手,进程的状态变迁,switch语句90%以上都是状态、)阻塞非阻塞 并发并行 同步异步 、系统调用、写实拷贝?、

命令

sed

利用脚本来处理文本文件,sed 可依照脚本的指令来处理、编辑文本文件。

Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等

  • a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~

  • c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!

  • d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;

  • i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);

  • p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~

  • s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦

sed -e 4a\newLine testfile //testfile文件的第四行后添加一行,并将结果输出到标准输出
sed -e '4 a newline\nnewline2' testfile //4 行之后追加 2 行:
//追加一行的话前后都不需要添加换行符 \n,只有追加多行时在行与行之间才需要添加换行符

[root@www ~]# nl /etc/passwd | sed '2,5d' //将 /etc/passwd 的内容列出并且列印行号,同时,请将第 2~5 行删除
nl /etc/passwd | sed '2d'  //只删除第二行
nl /etc/passwd | sed '3,$d' //删除第3到最后一行

[root@www ~]# nl /etc/passwd | sed '2a drink tea'//第二行后(也就是第三行)加上 drink tea
nl /etc/passwd | sed '2i drink tea' //第二行前加上drink tea

nl /etc/passwd | sed  '/root/d' //删除/etc/passwd所有包含root的行,其他行输出

进程

1. 编译连接过程、功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R28BBOex-1636470780563)(C:\Users\Lee Wen\AppData\Roaming\Typora\typora-user-images\image-20211025185629954.png)]

  1. 预编译:gcc -E main.c -o main.i

功能:

  • 删除所有的"#define",展开所有的宏定义
  • 处理所有预编译指令,"#if","#ifdef","#endif"
  • 处理"#include"指令,将被包含的文件插入到该预编译指令的位置
  • 删除所有注释
  • 添加行号和文件名标识,方便编译器产生调试用的符号信息以及有错误和警告时显示行号
  • 保留所有的#pragma编译器指令
  1. 编译 :gcc -S main.i -o main.s

功能:

语法、词法、语义分析,代码优化,汇总符号

  1. 汇编:gcc -c main.s -o main.o

功能:

将汇编指令翻译成二进制格式,生成各个section,生成符号表

  1. 链接:gcc main.o -o main

功能:

(1)合并各个section,合并符号表,进行符号解析,给符号分配虚拟地址

(2)符号重定位

2. makefile gdb

make

实现自动化编译

gcc 前面必须是table键缩进的

make命令根据makefile文件的规则生成可执行程序

//vi Makefile 第一个字母大写
 all: main
  
 main:main.o add.o max.o //依赖关系
     gcc -o main main.o add.o max.o//规则
 
 main.o:main.c
     gcc -c main.c
 add.o:add.c
     gcc -c add.c
 max.o:max.c
     gcc -c max.c
 
 clear:
     rm -rf *.o main //-r 如果没有main文件 不会报错
 
//vi main.c
#include<stdio.h>
   int add(int x,int y);
   int max(int x,int y);
    int main()
  {
      int a = 1;
      int b = 3;
      int c = add(a,b);
      int d = max(a,b);
  
      printf("a+b=%d\n",c);
      printf("a,b中最大的是:%d\n",d);
  
      return 0;
  }
//vi add.c
 #include<stdio.h>
 int add(int x,int y)
 {
         return x+y;
 }
//vi max.c
 #include<stdio.h>
 int max(int x,int y)
 {
     return x>y ? x : y;
 }

gdb

gcc -o main main.c add.c max.c -g   包含调试信息  

all : main

GDB = -g
main:main.o add.o max.o    //依赖关系
   gcc -o main main.o add.o max.o  //规则
   
main.o:main.c
   gcc -c main.c  $(GDB) //table缩进
add.o:add.c
   gcc -c add.c  $(GDB)
max.o:max.c
   gcc -c max.c   $(GDB)
  
clear:
   rm -rf *.o main

gdb main

l显示代码
b 12加断点
info break显示所有断点
delete 2删除编号为2的断点
r启动程序
n单步执行
p i输出i的值
p &i输出i的地址
q退出
s进入函数

3. 库文件

  1. 定义:预先编译好的方法(函数)的集合

  2. 两种形式:静态库 libxxx.a 共享库 libxxx.so

  3. < >说明是在标准库的include里面 #include<stdio.h>

    自己做的foo库是在./usr/lib里面

静态库

第一步:先将.c编译成.o目标文件

foo.h 里面包含函数的声明

add.c max.c 里面包含函数的定义

gcc -c add.c

gcc -c max.c

第二步:使用ar命令将第一步所有编译出的.o文件生成静态库

ar crv libfoo.a add.o max.o

c:创建库 r:将方法添加到库中 v: 显示过程

测试静态库

vi main.c

gcc -o main main.c -L. -lfoo

-L :指定库的存储路径 -l:指定库的名称(不需要前面的’lib’和扩展名’.a’)

. :表示库的存储路径在当前路径

共享库

第一步:先将.c编译成.o目标文件

foo.h 里面包含函数的声明

add.c max.c 里面包含函数的定义

gcc -c add.c

gcc -c max.c

第二步:使用gcc命令将第一步编译的.o文件生成共享库

gcc -shared -fPIC -o libfoo.so add.o max.o

测试共享库:

vi main.c

链接出main gcc -o main main.c -L. -lfoo

执行不成功 将libfoo.so移动到./usr/lib路径下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eFbQWBjr-1636470780566)(C:\Users\Lee Wen\AppData\Roaming\Typora\typora-user-images\image-20211028192005050.png)]

  • 通过ldd命令查看可执行程序使用了那些共享库 ldd main

静态库和共享库的区别

静态库:在链接时将用到的方法包含到最终生成的可执行程序中,执行过一次之后,即使删除了静态库也可以进行链接,因为已经将使用 的函数已经拷贝过来了

共享库:不进行复制,只做标记,在运行程序时,才动态加载,找不到则无法执行,如果删掉动态库,则函数将不能执行

4. 计算机基础

五大部件

  • 运算器:算术逻辑单元
  • 控制器:指挥计算机各部分协调的工作,保证计算机按照预先规定的目标和步骤有条不紊的进行操作
  • 存储器
  • 输入设备
  • 输出设备

进程

1.概念:正在运行的程序

2.PCB:进程控制块,进程存在的唯一标志

3.进程状态:就绪、运行、阻塞

4.并发、并行

前台 sleep 10

? 结束前台进程 CTRL C

? 停止进程 CTRL Z

后台 sleep 10 & 同时执行程序

kill -9 3665 强制结束进程

kill -stop 挂起进程

pkill 结束一组同名的进程

jobs 显示当前终端的任务

fg

? fg %任务号 将后台运行的或挂起的进程挪到前台执行

bg

bg %任务号 将挂起的进程唤醒到后台执行

5. 进程的复制与替换

printf

不会直接将数据输出到屏幕上,而是先放到缓冲区,在满足以下三种情况时,才会输出到屏幕

1.缓冲区满

2.强制刷新缓冲区 fflush

3.程序结束时

printf("hello"); 
sleep(3);     //先放在缓冲区中
exit(0);  exit()->fflush->_exit(0)  //先刷新再结束程序  
_exit(0);   //没有经过刷新就退出程序 
  • 没有\n会在缓冲区中等待情况满足在输出

  • 有\n在会直接输出

fork复制进程的过程

  1. pid_t pid = fork(); //pid_t是int类型

    #include<unistd.h> //Linux中必备的库函数
    #include<stdlib.h> //exit(0) 退出进程 0代表成功
    
    pid_t pid = fork();   //pid_t是int类型
    getpid()  //得到当前进程的pid
    getppid() //得到父进程的pid号
    
  2. 首先先给予一个新的进程号,在复制一份PCB,再复制父类的进程 生成的子进程,与父进程的大小相同

  3. fork在父进程中返回的是子进程的pid,在子进程中成功返回0,失败返回-1;
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

注:在父进程执行完fork()之后才出现子进程

? 子进程不是从最开始执行,而是从fork()之后开始执行

? 父子进程中的n不是同一块地址空间

? main程序的父进程是3280 bash

? 0号进程没有父进程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

僵死进程概念及处理方法

  1. 概念:子进程先于父进程结束,父进程没有调用wait获取子进程退出码

  2. 处理方法:父进程通过调用wait()完成

    //运行时 ./fork &  要放在后台运行才能看见僵死进程
    wait
    
    WIFEXITED(val)   //判断程序是不是正常结束
    
    WEXITSTATUS(val)  //获取该进程的退出码
    

在这里插入图片描述

子进程结束后并没有消失,仍然可以在系统中观察到,但此时的子进程已经结束了,此时子进程的状态称为僵死状态,把处于该类状态的进程称为僵死进程

如果是父进程先结束,子进程是不会变成僵死进程的

在这里插入图片描述

子进程结束后,父进程会获得他的退出码

  1. 父子进程会共享父进程fork之前打开的所有文件描述符

6. file

1. 文件描述符

是一个非负的索引值(一般从3开始,0,1,2已经被使用),指向内核中的“文件记录表”,

  • 当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符(内核记录表某一栏的索引);

  • 当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数。

  • Linux 下所有对设备和文件的操作都使用文件描述符来进行。

    1. 常见的文件描述符类型
  • ” 0 “:表示标准输入,对应宏为:STDIN_FILENO,函数 scanf() 使用的是标准输入;

  • “ 1 ”:表示标准输出,对应宏为:STDOUT_FILENO, 函数 printf() 使用的是标准输出;

  • “ 2 ”:表示标准出错处理,对应的宏为:STDERR_NO;
    你也可以使用函数 fscanf() 和 fprintf() 使用不同的 文件描述符 重定向进程的 I/O 到不同的文件。

  • 若要访问文件,而且调用的函数又是 writereadopenclose时,就必须用到文件描述符(一般从3开始)。
  • 若调用的函数为 fwritefreadfopenfclose时,就可以绕过直接控制文件描述符,使用的则是与文件描述符对应的文件流
int open(const char* pathname,int flags);
//打开一个已存在的文件  返回值是文件描述符
int open(const char* pathname,int flags,mode_t mode);
//新建一个文件并设置访问权限  返回值是文件描述符
ssize_t read(int fd,void* buf,size_t count);//fd:对应文件的文件描述符,buf:存放数据的空间,count:想要读到的字节数据  返回值:实际读到的字节数
ssize_t write(int fd,const void* buf,size_t count);//
int close(int fd);

2. 系统调用和库函数的区别

2.1 系统调用
  1. 系统调用指运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务。它通过软中断向内核态发出一个明确的请求。系统调用实现了用户态进程和硬件设备之间的大部分接口。

  2. 常见系统调用
    open, close, read, write, ioctl,fork,clone,exit,getpid,access,chdir,chmod,stat,brk,mmap等,需要包含unistd.h等头文件。

2.2 库函数
  1. 库函数用于提供用户态服务。它可能调用封装了一个或几个不同的系统调用(printf调用write),也可能直接提供用户态服务(atoi不调用任何系统调用)。

  2. 常见库函数
    printf,scanf,fopen,fclose,fgetc,fgets,fprintf,fsacnf,fputc,calloc,free,malloc,realloc,strcat,strchr,strcmp,strcpy,strlen,strstr等,需要包含stdio.h,string.h,malloc.h,stdlib.h等头文件。

2.3 区别

1.系统调用运行在内核空间,库函数运行在用户空间

如果当用户态进程调用一个系统调用时,CPU需要将其切换到内核态,并执行一个内核函数。

2.内核调用返回的是一个整数值,库函数不一定

在内核中,整数或0表示系统调用成功结束,而负数表示一个出错条件。而出错时,内核不会将其设置在errno,而是由库函数从系统调用返回后对其进行设置或使用。

3.系统调用运行时间属于系统时间,库函数运行时间属于用户时间

4.调用系统调用开销比库函数更大

5.系统调用不可替换,库函数通常可以替换

普通的库函数调用由函数库或用户自己提供,因此库函数是可以替换的

2.4 内核态和用户态的区别

1.操作系统需要两种CPU状态

内核态:运行操作系统程序,操作硬件

用户态:运行用户程序

用户态到内核态:程序运行中断、异常、系统调用

2.区别

  • 运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。当我们在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成某些它没有权力和能力完成的工作时就会切换到内核态

  • 处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所处于占有的处理器是可被抢占的

  • 处于内核态执行时,则能访问所有的内存空间和对象,且所占有的处理器是不允许被抢占的。

7. 信号

#include<signal.h> //调用文件的头文件
名称说明
SIGINT终端中断2
SIGKILL终止终端9
SIGPIPE向无读进程的管道写数据 读端关闭 写端写入时,该信号会终止程序13
SIGTERM命令kill默认发送的信号15
SIGCHLD子进程结束后 默认给父进程发送该信号17

1. signal()

改变信号响应方式

ctrl+c 会给当前终端执行的进程发送SIGINT信号

void fun(int sign) //自己写的信号处理函数 接收到信号后就输出信号值
{
    printf("fun was called,sign = %d\n",sign);
}

int main()
{
   signal(SIGINT,fun); //修改响应的方式 本来要终止 现在就去调用fun函数
    for(int i = 0;i< 10; ++i)
   {
        sleep(1);
        printf("main running\n");
    }

    exit(0);
}

2. kill()

发送信号

向指定的进程发送指定的信号

int kill(pid_t pid,int sig);

pid > 0 指定将信号发送给那个进程

pid == 0 发送到和当前进程在同一个进程组的进程

pid == -1 发送给系统上有权限发送的所有进程

pid < -1 发送给进程组id等于pid绝对值,并且有权限发送大所有进程

sig 指定发送信号的类型

文件传输

查看服务、删除、下载文件、上传

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-11-10 12:49:03  更:2021-11-10 12:50:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 23:04:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码