Linux系统编程(一):基本概念

参考引用

  • Unix和Linux操作系统有什么区别?
  • 一文带你彻底搞懂posix

Linux系统编程(文章链接汇总)

1. Unix 和 Linux

在这里插入图片描述

1.1 Unix

  • Unix 操作系统诞生于 1969 年,贝尔实验室发布了一个用 C 语言编写的名为「Unix」的操作系统,该系统可以更快地修改、调整与移植适配
    • Unix 操作系统主要在 CLI(命令行界面)上工作
    • Unix 的个人用户不多,主要使用集中在商业领域

1.2 Linux

  • 1991 年,芬兰大学生 Linus Torvalds 开发了一个自由的内核(Linux 这个名字来自于其使用的内核名称)
    • 1992 年,把 Linux 和 GNU 系统结合起来,就构成一个完整的操作系统:基于 Linux 的 GNU 系统(GNU/linux)
    • Linux 并没有使用 Unix 的源码,而是按照公开的 POSIX 标准重新编写

1.3 二者对比

  • Linux 思想源于 Unix,以 Unix 为原型开发的
  • Linux 完全开源,Unix 是版权专有
  • Linux 狭义上是指 GNU/Linux 操作系统使用的内核,广义上讲,是一种「类Unix」操作系统;Unix 狭义上是指贝尔实验室最初开发的一整套操作系统,广义上讲是属于符合「Unix」标准的一类操作系统
  • Linux 的默认 shell 是 BASH;而 Unix 用的是 Bourne shell

1.4 其他

  • Linux(不包含 GNU 组件) 是 Android(2007.11) 的内核
  • 苹果使用 UNIX 作为 iOS(2007.1) 和 macOS 的内核

2. Ubuntu 和 Linux

  • Linux 是一个开源的操作系统内核(一个 640KB文件,在 /Boot 目录下),而 Ubuntu 是基于 Linux 内核开发的一个完整的操作系统,具体而言,Ubuntu 是基于 Debian 发行版的 Linux 操作系统

3. POSIX 标准

3.1 定义

  • POSIX(Portable Operating System Interface,可移植操作系统接口
  • POSIX 是 IEEE 为了在各种 UNIX 操作系统上运行的软件而定义的一系列 API 标准的总称
  • POSIX.1 已被国际标准化组织(International Standards Organization,ISO)接受,命名:ISO/IEC 9945-1:1990

3.2 历史

  • 为了提高兼容性和应用程序的可移植性,IEEE 开始标准化 Unix 的开发,由 Richard Stallman 命名为 POSIX,这套标准涵盖了很多方面,比如 Unix 系统调用的 C 语言接口、shell 程序和工具、线程及网络编程
  • Unix 和 Linux 均遵循 POSIX 标准
  • 有了这个规范,就可以调用通用的 API,Linux 提供的 POSIX 系统调用在 Unix 上也能执行

4. 系统调用和库函数

  • Linux 下对文件操作有两种方式:系统调用(system call)和库函数(Library functions)

4.1 系统调用

  • 系统调用是 Linux 内核提供给应用层的应用编程接口(API),是 Linux 应用层进入内核的入口,内核提供了一系列服务、资源、支持等,应用程序通过系统调用 API 函数来使用内核提供的服务、资源以及各种各样的功能
  • 通过系统调用 API 函数,应用层可以实现与内核的交互,其关系可通过下图简单描述
    在这里插入图片描述

Linux 应用编程(系统编程)与裸机编程、驱动编程有什么区别?

  • 1. 裸机编程:一般把没有操作系统支持的编程环境称为裸机编程环境,如:单片机上的编程开发,编写直接在硬件上运行的程序,没有操作系统支持
  • 2. 驱动编程:狭义上 Linux 驱动编程指的是基于内核驱动框架开发驱动程序,驱动开发工程师通过调用 Linux 内核提供的接口完成设备驱动的注册,驱动程序负责底层硬件操作相关逻辑
  • 3. 应用编程:基于 Linux 操作系统的应用编程,在应用程序中通过调用系统调用 API 完成应用程序的功能和逻辑,应用程序运行于操作系统之上。通常在操作系统下有两种不同的状态:内核态和用户态,应用程序运行在用户态,而内核则运行在内核态

4.2 库函数

  • 库函数(Library function)是把函数放到库里,供别人使用的一种方式,库函数调用面向应用开发,可分为两类
    • 一类是 C 语言标准规定的库函数
    • 一类是编译器特定的库函数
  • C 语言库是应用层使用的一套函数库,在 Linux 下通常以动态库文件(.so)形式提供,存放在根文件系统 /lib/x86_64-linux-gnu 目录,命名方式通常是 libc.so.6,不过这是一个软链接文件,它会链接到真正的库文件,C 语言库函数构建于系统调用之上,也就是说大部分库函数其实是由系统调用封装而来
    • 有些库函数并不调用任何系统调用,如:字符串处理函数 strlen()、strcat()、memcpy()、memset()、strchr()等
    • 有些库函数会使用系统调用来完成实际操作,如:库函数 fopen 内部调用了系统调用 open() 来帮它打开文件、库函数 fread() 就利用了系统调用 read() 来完成读文件操作、fwrite()就利用了系统调用 write()来完成写文件操作

为什么需要库函数?

  • 有些系统调用使用起来并不是很方便,于是就出现了 C 语言库,这些 C 语言库函数的设计是为了提供比底层系统调用更为方便、更为好用、且更具有可移植性的调用接口

4.3 标准 C 语言函数库

  • 在 Linux 系统下,使用的 C 语言库为 GNU C 语言函数库(也叫 glibc),作为 Linux 下的标准 C 语言函数库。glibc 为程序员提供丰富的 API,这些 API 的函数名、返回值和参数类型等都必须按照 POSIX 标准来定义
  • 确定 Linux 系统的 glibc 版本
    $ cd /lib/x86_64-linux-gnu
    $ ls -l libc.so.6    # libc.so.6 软链接到 libc-2.27.so 库文件,2.27 便是 Linux 系统的 glibc 版本
    lrwxrwxrwx 1 root root 12 5月   3  2022 libc.so.6 -> libc-2.27.so
    

4.4 二者对比

  • 库函数属于应用层,而系统调用是内核提供给应用层的编程接口,属于系统内核的一部分
  • 库函数运行在用户空间,调用系统调用会由用户空间(用户态)陷入到内核空间(内核态)
  • 库函数通常是有缓存的,而系统调用是无缓存的,所以在性能、效率上,库函数通常要优于系统调用
    • 库函数调用属于过程调用,运行时间为用户时间,开销较小
    • 系统调用需要在用户态和内核态之间切换,运行时间为系统时间,开销较大
  • 可移植性:库函数相比于系统调用具有更好的可移植性,通常对于不同的操作系统,其内核向应用层提供的系统调用往往都是不同的,而对于 C 语言库函数来说,由于很多操作系统都实现了 C 语言库,C 语言库在不同的操作系统之间其接口定义几乎是一样的,所以库函数在不同操作系统之间相比于系统调用具有更好的可移植性

4.5 系统调用流程

  • 当应用程序调用 printf() 函数时,printf() 函数会调用 C 库中的 printf(),继而调用 C 库中的 write(),C 库最后调用内核的 write()
    • printf() 函数执行过程中,程序运行状态切换如下
    用户态–>系统调用–>内核态–>返回用户态
    

在这里插入图片描述

  • printf() 函数、glibc 库和系统调用在系统中关系图如下
    在这里插入图片描述

  • 实例

    // test.c
    #include <stdio.h>int main(int argc, char **argv) {printf("Hello world!");   return 0;
    }   
    
    $ gcc test.c -o test
    $ strace test  # 运行程序前加上 strace,可以追踪库函数调用过程
    execve("./test3", ["./test3"], 0x7fffb2493520 /* 82 vars */) = 0
    brk(NULL)                               = 0x560a8c38b000
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/opt/ros/melodic/lib/tls/x86_64/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/opt/ros/melodic/lib/tls/x86_64/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/opt/ros/melodic/lib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/opt/ros/melodic/lib/tls/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/opt/ros/melodic/lib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/opt/ros/melodic/lib/tls/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/opt/ros/melodic/lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/opt/ros/melodic/lib/tls", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/opt/ros/melodic/lib/x86_64/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/opt/ros/melodic/lib/x86_64/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/opt/ros/melodic/lib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/opt/ros/melodic/lib/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/opt/ros/melodic/lib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/opt/ros/melodic/lib/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/opt/ros/melodic/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/opt/ros/melodic/lib", {st_mode=S_IFDIR|0755, st_size=16384, ...}) = 0
    openat(AT_FDCWD, "/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/tls/x86_64/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/tls/x86_64/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/tls/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/tls/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/tls", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/x86_64/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/x86_64/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/x86_64", 0x7ffff162afb0) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    stat("/home/yue/PX4-Autopilot/build/px4_sitl_default/build_gazebo", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
    openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=274620, ...}) = 0
    mmap(NULL, 274620, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2f5e388000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\35\2\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0755, st_size=2030928, ...}) = 0
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2f5e386000
    mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2f5ddb2000
    mprotect(0x7f2f5df99000, 2097152, PROT_NONE) = 0
    mmap(0x7f2f5e199000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f2f5e199000
    mmap(0x7f2f5e19f000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2f5e19f000
    close(3)                                = 0
    arch_prctl(ARCH_SET_FS, 0x7f2f5e3874c0) = 0
    mprotect(0x7f2f5e199000, 16384, PROT_READ) = 0
    mprotect(0x560a8c066000, 4096, PROT_READ) = 0
    mprotect(0x7f2f5e3cc000, 4096, PROT_READ) = 0
    munmap(0x7f2f5e388000, 274620)          = 0
    fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
    brk(NULL)                               = 0x560a8c38b000
    brk(0x560a8c3ac000)                     = 0x560a8c3ac000
    write(1, "Hello world!", 12Hello world!)            = 12
    exit_group(0)                           = ?
    +++ exited with 0 +++
    
  • 程序虽然只有一个printf函数,但在执行过程中前后调用了 execve、access、open、fstat、mmap、brk、write 等系统调用。其中 write 系统调用会把字符串 Hello world! 通过设备文件 1 发送到驱动,该设备节点对应终端 stdout

    $ ls /dev/std* -l
    lrwxrwxrwx 1 root root 15 12月 11 21:10 /dev/stderr -> /proc/self/fd/2
    lrwxrwxrwx 1 root root 15 12月 11 21:10 /dev/stdin -> /proc/self/fd/0
    lrwxrwxrwx 1 root root 15 12月 11 21:10 /dev/stdout -> /proc/self/fd/1
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/214470.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【基于LSTM的电商评论情感分析:Flask与Sklearn的完美结合】

基于LSTM的电商评论情感分析&#xff1a;Flask与Sklearn的完美结合 引言数据集与爬取数据处理与可视化情感分析模型构建Flask应用搭建词云展示创新点结论 引言 在当今数字化时代&#xff0c;电商平台上涌现出大量的用户评论数据。了解和分析这些评论对于企业改进产品、服务以及…

以太坊:前世今生与未来

一、引言 以太坊&#xff0c;这个在区块链领域大放异彩的名字&#xff0c;似乎已经成为了去中心化应用&#xff08;DApps&#xff09;的代名词。从初期的萌芽到如今的繁荣发展&#xff0c;以太坊经历了一段曲折而精彩的旅程。让我们一起回顾一下以太坊的前世今生&#xff0c;以…

树实验代码

哈夫曼树 #include <stdio.h> #include <stdlib.h> #define MAXLEN 100typedef struct {int weight;int lchild, rchild, parent; } HTNode;typedef HTNode HT[MAXLEN]; int n;void CreatHFMT(HT T); void InitHFMT(HT T); void InputWeight(HT T); void SelectMi…

【Qt开发流程】之UI风格、预览及QPalette使用

概述 一个优秀的应用程序不仅要有实用的功能&#xff0c;还要有一个漂亮美腻的外观&#xff0c;这样才能使应用程序更加友善、操作性良好&#xff0c;更加符合人体工程学。作为一个跨平台的UI开发框架&#xff0c;Qt提供了强大而且灵活的界面外观设计机制&#xff0c;能够帮助…

利用Rclone将阿里云对象存储迁移至雨云对象存储的教程,对象存储数据迁移教程

使用Rclone将阿里云对象存储(OSS)的文件全部迁移至雨云对象存储(ROS)的教程&#xff0c;其他的对象存储也可以参照本教程。 Rclone简介 Rclone 是一个用于和同步云平台同步文件和目录命令行工具。采用 Go 语言开发。 它允许在文件系统和云存储服务之间或在多个云存储服务之间…

STM32-EXTI外部中断

目录 一、中断系统 二、STM32中断 三、NVIC&#xff08;嵌套中断向量控制器&#xff09;基本结构 四、NVIC优先级分组 五、EXTI外部中断 5.1 外部中断基本知识 5.2 外部中断&#xff08;EXTI&#xff09;基本结构 ​编辑 5.2.1开发步骤&#xff1a; 5.3 AFIO复用IO口…

ADAudit Plus:强大的网络安全卫士

随着数字化时代的不断发展&#xff0c;企业面临着越来越复杂和多样化的网络安全威胁。在这个信息爆炸的时代&#xff0c;保护组织的敏感信息和确保网络安全已经成为企业发展不可或缺的一环。为了更好地管理和监控网络安全&#xff0c;ADAudit Plus应运而生&#xff0c;成为网络…

Redis分布式锁有什么缺陷?

Redis分布式锁有什么缺陷&#xff1f; Redis 分布式锁不能解决超时的问题&#xff0c;分布式锁有一个超时时间&#xff0c;程序的执行如果超出了锁的超时时间就会出现问题。 1.Redis容易产生的几个问题&#xff1a; 2.锁未被释放 3.B锁被A锁释放了 4.数据库事务超时 5.锁过期了…

centos 7 卸载图形化界面步骤记录

centos7 服务器操作系统&#xff0c;挺小一配置&#xff0c;装了图形化界面&#xff0c;现在运行程序的时候跑不动了&#xff0c;我想这图形界面也没啥用&#xff0c;卸载了算了&#xff01; 卸载步骤 yum grouplist 查询已经安装的组件 可以看到 图形化界面 等是以分组存在的…

TCP数据粘包的处理

TCP数据粘包的处理 背锅侠TCP解决方案2.1 发送端2.2 接收端 背锅侠TCP 在前面介绍套接字通信的时候说到了TCP是传输层协议&#xff0c;它是一个面向连接的、安全的、流式传输协议。因为数据的传输是基于流的所以发送端和接收端每次处理的数据的量&#xff0c;处理数据的频率可…

Qt练习题

1.使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否…

【Angular开发】Angular 16发布:发现前7大功能

Angular 于2023年5月3日发布了主要版本升级版Angular 16。作为一名Angular开发人员&#xff0c;我发现这次升级很有趣&#xff0c;因为与以前的版本相比有一些显著的改进。 因此&#xff0c;在本文中&#xff0c;我将讨论Angular 16的前7个特性&#xff0c;以便您更好地理解。…

机器学习基础介绍

百度百科&#xff1a; 机器学习是一门多领域交叉学科&#xff0c;涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为&#xff0c;以获取新的知识或技能&#xff0c;重新组织已有的知识结构使之不断改善自身的性能。 …

手工酸奶店如何选址?开在哪里比较合适?

手工酸奶店是一个非常受欢迎的创业项目&#xff0c;但想要成功开店&#xff0c;选址是非常重要的。 本人开酸奶店5年时间&#xff0c;下面我将为大家分享一些选址的小技巧&#xff0c;希望对大家有所帮助。&#xff08;可以点赞收藏&#xff0c;方便以后随时查阅&#xff09; …

入职字节外包一个月,我离职了。。。

有一种打工人的羡慕&#xff0c;叫做“大厂”。 真是年少不知大厂香&#xff0c;错把青春插稻秧。 但是&#xff0c;在深圳有一群比大厂员工更庞大的群体&#xff0c;他们顶着大厂的“名”&#xff0c;做着大厂的工作&#xff0c;还可以享受大厂的伙食&#xff0c;却没有大厂…

12.11 C++ 作业

完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&#xf…

树根研习社|数据为王,洞察“工业数据采集”背后的价值与实践

一、工业数据采集是什么&#xff1f; 数据采集是将各种信息传感设备通过网络结合起来&#xff0c;实现任何时间、任何地点&#xff0c;人、机、物的互联互通。数据采集的主要的作用是&#xff1a; “翻译官”&#xff1a;不同程序语言的设备数据通过协议解析“翻译”为上层系…

淘宝权益玩法平台的Serverless化实践

通过对权益玩法平台现有业务应用的Serverless化改造&#xff0c;权益团队在双十一期间完美地支撑了业务需求&#xff0c;在研发效率、运维保障等方面都体现出了很高的价值和收益。 项目背景 淘宝权益平台是负责淘宝权益营销的核心团队&#xff0c;团队除了负责拉菲权益平台外&a…

1.cloud-微服务架构编码构建

1.微服务cloud整体聚合父工程 1.1 New Project 1.2 Maven选版本 1.3 字符编码 1.4 注解生效激活 主要为lombok中的Data 1.5 java编译版本选8 1.6 File Type过滤 *.hprof;*.idea;*.iml;*.pyc;*.pyo;*.rbc;*.yarb;*~;.DS_Store;.git;.hg;.svn;CVS;__pycache__;_svn;vssver.scc;v…

Nginx配置文件的基本用法

Nginx简介 1.1概述 Nginx是一个高性能的HTTP和反向代理服务器。 是一款轻量级的高性能的web服务器/反向代理服务器/电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器 单台物理服务器可支持30 000&#xff5e;50 000个并发请求。 1.2Nginx和Apache的优缺点 &#xff…