Linux 系统编程
- 简介和主要概念
- Linux 系统编程最突出的特点是要求系统程序员对它们工作的的系统的硬件和操作系统有深入和全面的了解,当然它们还有库和系统调用上的区别。
- 系统编程分为:驱动编程、用户空间编程和网络编程。
- 系统编程有三大基石:系统调用、C库和C编译器。
- 文件I/O
- 文件I/O是Unix系统的核心,第三章会介绍基于C标准库的标准I/O,第四章继续讨论了更高级和专门化的I/O, 第七章以文件盒目录操作为主题结束了整个文件I/O部分的讨论。
- 文件I/O包括 open, creat, read, write, close fsync(同步I/O), fdatasync(同步I/O),sync(同步I/O), lseek, truncate 函数。
- Linux 提供了三种 I/O 多路复用的方法,select , poll , epoll。这三种方式有各自的优缺点,具体参考:
- 缓冲输入输出
- 要理解缓冲,首先要理解块,作为文件系统的抽象,它是 I/O 中最基本的概念,所有的磁盘操作都是基于块进行的。因此当请求以块大小整数倍对齐地址时, I/O 效率是最理想的。
- 标准 I/O 例程并不直接操作文件描述符,取而代之的是文件指针(file pointer)。在C标准库里,文件指针映射到文件描述符。
- 在标准 I/O 里,一个打开的文件叫做“流”(stream)。
- 标准 I/O 包括 fopen, fdopen, fclose, fclose, fgetc, ungetc, fgets, fread, fputc, fputs, fwrites, fseek, ftell, ferror, fileno, setvbuf 等等。
- 标准 I/O 最大的缺点是双副本对性能造成的影响。当读取数据时,标准 I/O 对内核执行read()系统调用,从内核复制数据到标准 I/O 缓冲区。然后当通过标准 I/O 执行一个读请求时,数据又会从标准 I/O 的缓冲区复制到指定的缓冲区。
- read/write和fread/fwrite区别
- fread是带缓冲的,read不带缓冲.
- fopen是标准c里定义的,open是POSIX中定义的.
- fread可以读一个结构.read在linux/unix中读二进制与普通文件没有区别.
- fopen不能指定要创建文件的权限.open可以指定权限.
- fopen返回指针,open返回文件描述符(整数).
- linux/unix中任何设备都是文件,都可以用open,read.
- 如果文件的大小是8k。你如果用read/write,且只分配了2k的缓存,则要将此文件读出需要做4次系统调用来实际从磁盘上读出。如果你用fread/fwrite,则系统自动分配缓存,则读出此文件只要一次系统调用从磁盘上读出。也就是用read/write要读4次磁盘,而用fread/fwrite则只要读1次磁盘。效率比read/write要高4倍。如果程序对内存有限制,则用read/write比较好。都用fread 和fwrite,它自动分配缓存,速度会很快,比自己来做要简单。如果要处理一些特殊的描述符,用read 和write,如套接口,管道之类的系统调用write的效率取决于你buf的大小和你要写入的总数量,如果buf太小,你进入内核空间的次数大增,效率就低下。而fwrite会替你做缓存,减少了实际出现的系统调用,所以效率比较高。
- 如果只调用一次(可能吗?),这俩差不多,严格来说write要快一点点(因为实际上fwrite最后还是用了write做真正的写入文件系统工作),但是这其中的差别无所谓。
- 高级文件I/O
- 主要分为
- 散步/聚集I/O 允许在单次调用中对多个缓冲区做读取和写入操作。 readv 和 writev
- epoll
- 内存映射I/O 将文件映射到内存, mmap, munmap, mremap
- 文件I/O提示 posux_fadvise() 和 readahead()
- 异步I/O
- 进程管理
- 进程是操作系统的基础,是程序的一次执行。是程序及其数据在处理机上顺序执行时所发生的活动。
- 有两种方式创建新的进程:
- fork 调用会导致创建一个子进程
- exec调用则会用新的程序代替当前进程的上下文
- 终止进程有以下几种方式:
- exit
- SIGTERM 和 SIGKILL
- 子进程退出后,转变为僵尸进程,父进程调用 wait 和 waitpid 使得子进程完全退出
- 许多Unix系统在他们的C函数库中提供了 daemon() 函数来完成 守护进程的创建工作。
- 高级进程管理
- Linux 调度算法采用抢占多任务机制,支持多处理器,处理器亲和度,非一致内存访问,实时进程和用户自定义优先级等特性
- 进程优先级 gerpriority() 和setpriority()
- 更多的进程管理参考:
- 7. 文件与目录管理
- 8. 内存管理
- 内存管理包括: 存储器分配(allocation),内存操控(manipulation)和最后的内存释放(release)
- 进程地址空间
- 内存的基本单位是页,32位系统是4K,64位系统是8K
- 每个进程所包含的存储器区域为:
- 代码段(文本段)
- 栈空间
- 堆空间(数据段)
- BBS段 --包含了没有被初始化的全局变量
- 动态内存分配
- malloc , calloc , realloc
- 动态内存释放
- free
- 内存对齐
- 一个结构的对齐要求和它的成员中最大的那个类型是一样的
- 结构体也需要内存对齐
- union的对齐和它所包含的最大的类型一致
- 一个数组的对齐和数组中的元素类型一致
- 匿名存储映射
- 优点:
- 无需关心碎片
- 大小可调整
- 每个分配存在于独立的内存映射,没有必要再求管理一个全局的堆
- 缺点:
- 存储器映射都是页面大小的倍数,容易浪费空间
- 创建一个新的内存映射比从对中返回内存的负载要大
- malloc()使用数据段满足小的分配,匿名存储映射用来满足较大的分配
- 高级存储器分配
- mallopt() 设置存储器管理相关的参数
- malloc_usable_size()和 malloc_trim() 进行调优
- 使用 MALLOC_CHECK 环境变量来开启存储系统额外的调试
- MALLOC_CHECK_=1 ./rudder
- 使用 mallinfo() 来获得关于动态存储分配的统计数据

9. 信号
- 信号是提供处理异步事件机制的软件中断。
- 内核处理信号的三种方式:
- 忽略信号 SIGKILL 和 SIGSTOP 不可以被忽略
- 捕获并处理信号
- 执行默认操作,通常是终止程序
- 映射信号编号为字符串
- extern const char * const sys_siglist[];
- printf("caught %s\n", sys_siglist[signo]);
- 发送信号
- kill()
- 高级信号管理
- sigaction()
Linux 系统编程的更多相关文章
- Linux系统编程温故知新系列 --- 01
1.大端法与小端法 大端法:按照从最高有效字节到最低有效字节的顺序存储,称为大端法 小端法:按照从最低有效字节到最高有效字节的顺序存储,称为小端法 网际协议使用大端字节序来传送TCP分节中的多字节整数 ...
- linux系统编程之错误处理
在linux系统编程中,当系统调用出现错误时,有一个整型变量会被设置,这个整型变量就是errno,这个变量的定义在/usr/include/errno.h文件中 #ifndef _ERRNO_H /* ...
- LINUX系统编程 由REDIS的持久化机制联想到的子进程退出的相关问题
19:22:01 2014-08-27 引言: 以前对wait waitpid 以及exit这几个函数只是大致上了解,但是看REDIS的AOF和RDB 2种持久化时 均要处理子进程运行完成退出和父进程 ...
- Linux系统编程-setitimer函数
功能:linux系统编程中,setitimer是一个经常被使用的函数,可用来实现延时和定时的功能. 头文件:sys/time.h 函数原型: int setitimer(int which, cons ...
- Linux系统编程@进程通信(一)
进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...
- Linux C 程序 文件操作(Linux系统编程)(14)
文件操作(Linux系统编程) 创建一个目录时,系统会自动创建两个目录.和.. C语言实现权限控制函数 #include<stdio.h> #include<stdlib.h> ...
- 读书笔记之Linux系统编程与深入理解Linux内核
前言 本人再看深入理解Linux内核的时候发现比较难懂,看了Linux系统编程一说后,觉得Linux系统编程还是简单易懂些,并且两本书都是讲Linux比较底层的东西,只不过侧重点不同,本文就以Linu ...
- Linux系统编程【转】
转自:https://blog.csdn.net/majiakun1/article/details/8558308 一.Linux系统编程概论 1.1 系统编程基石 syscall: libc:标准 ...
- linux系统编程:cp的另外一种实现方式
之前,这篇文章:linux系统编程:自己动手写一个cp命令 已经实现过一个版本. 这里再来一个版本,涉及知识点: linux系统编程:open常用参数详解 Linux系统编程:简单文件IO操作 /*= ...
随机推荐
- linux入门教程(三) Linux操作系统的安装
因为笔者一直都是使用CentOS,所以这次安装系统也是基于CentOS的安装.把光盘插入光驱,设置bios光驱启动.进入光盘的欢迎界面. 其中有两个选项,可以直接按回车,也可以在当前界面下输入 lin ...
- 关于项目中遇到的NullPointerException异常时处理手段
在项目开发中,经常会遇到NullPointerException异常,特别是一些新手,非常的郁闷,有时候会很隐蔽,特别是不同的人书写的代码进行调用时. 以下是我所遇到的NullPointerExcep ...
- iOS 开发--github的demo
令人惊讶的是,YYText 虽然代码量很大(超过一万行),但它只是 ibireme 的作品之一.ibireme 利用业余时间完成了 YYKit 工具库,包括: YYModel — 高性能的 iOS J ...
- QC、IQC、IPQC、FQC、OQC、QA分别的定义
QC:即英文(Quality Control)的简称,中文意义是品质控制,其在ISO8402:1994的定义是“为达到品质要求所采取的作业技术的活动”.有些推行ISO9000的组织会设置这样一个部门或 ...
- liunx下tomcat启动报错
liunx下tomcat启动 Cannot find ./catalina.sh 2013-08-23 11:50 1521人阅读 评论(0) 收藏 举报 Cannot find ./catalina ...
- Java NIO原理图文分析及代码实现
原文: http://weixiaolu.iteye.com/blog/1479656 目录: 一.java NIO 和阻塞I/O的区别 1. 阻塞I/O通信模型 2. java ...
- 如何用Maven创建一个普通Java项目
一下内容包括:用Maven创建一个普通Java项目,并把该项目转成IDEA项目,导入到IDEA,最后把这个项目打包成一个jar文件. 有时候运行mvn命令失败,重复运行几次就OK了,无解(可能因为网络 ...
- 重写hashCode()的方法
重写hashCode()方法的基本规则: 1.在程序运行过程中,同一个对象多次调用hashCode()方法应该返回相同的值 2.当两个对象通过equals()方法比较返回true时,这两个对象的has ...
- POJ 1808 Quadratic Residues(平方剩余相关)
题目链接:http://poj.org/problem?id=1808 题意:如下.对于素数p,若存在x使得x^2%p=a,则其值为1.否则为-1.现在给出a.p,计算其值. 思路: 若a为正数则利用 ...
- 预定义的类型“Microsoft.CSharp.RuntimeBinder.Binder”未定义或未导入
http://www.mzwu.com/article.asp?id=3611 因为新加了Microsoft.CSharp的引用, 只需要重新生成一下项目,就可以消除这个错误提示