【读书笔记】linux/unix系统编程

第三章 系统编程概念

  • 与用户空间函数调用相比,最简单的系统调用会产生比较大的打开,因为为了执行系统调用,系统需要临时切换到核心态,发生中断,此外,内核还需要验证系统调用的参数,用户内存和内核内存之间的数据需要传递
// 如果代码里有pidof()需要,可以换一种方式实现
while true:
do
	local pid_s = `pidof super`
fi
sleep 5
done
// 改进的程序
local pid_s = `pidof super`
while true:
do
	if [ -z $pid_s ] || [ ! -d /proc/$pid_s ]; then
        do something
fi
sleep 5
done

第五章 文件io

5.1 原子操作和竞争条件

如果一个进程执行到lseek()和write()之间,被执行相同代码的第二个进程中断,那么这两个进程会在写入数据前,将文件偏移量设为相同位置,而当一个进程再次获得调度时,会覆盖第二个进程已写入的数据(脏数据)。

if (lseek(fd, 0, SEEK_END) == -1)
    errExit("lseek");
if (write(fd, buf, len) != len) 
    fatal("Partial/failed write");

规避这一问题,可以在打开文件加入O_APPEND标志。

  • 文件特定偏移量处的IO:pread和pwrite,具有原子性- 分散输入和集中输出,readv() writev(),也属于原子操作
  • preadv(), pwritev(), 增加了offset参数
  • truncate() ftruncate, 可以将文件大小设为length参数指定值
  • 非阻塞io, O_NONBLOCK
  • 大文件io,2gb内,fopen64(), open64(), lseek64(), truncate64()
  • /dev/fd 内核给每个进程提供一个特殊的虚拟目录/dev/fd
  • 创建临时文件,mkstemp, tmpfile

第六章 进程

进程pid
  • 进程pid,最大是32767,如果超过,内核将进程号计数器重置为300(因为300以内通常是系统进程,为了减少没必要的检索)。可以通过/proc/sys/kernel/pid_max修改pid最大阈值

第七章 内存分配

内存一些错误
  • 分配内存后,不要改变这块内存范围外的内容
  • 释放同一块内存,会报sigsegv信号
  • 没有经过malloc函数返回的指针,不能调用free
  • 长时间运行的程序,如果反复分配内存,应确保用完就释放
内存调试的工具和库
  • mtrace() muntrace() 开发或关闭对内存分配调用进行跟踪功能
  • mcheck() mprobe() 允许程序对分配内存进行一致性检查
  • MALLOC_CHECK_ 环境变量提供了类似mcheck() 和mprobe()函数的功能
在堆上分配内存其他方法
  • calloc 对已分配的内存初始化为0
  • realloc 增加已分配内存的大小,不会初始化
  • memalign() posix_memalign() 分配内存时,起始地址要与2的整数次幂对齐
在堆栈上分配内存 alloca()

动态分配内存,通过增加栈帧大小从堆栈上分配
缺点:堆栈溢出时,无法预知,没有返回NULL
优点:1. 分配内存速度比malloc快,因为编译器将alloca()作为内联代码处理; 2. alloca分配的内存随栈帧的溢出自动释放

第13章 文件IO缓冲

13.1 缓冲区大小对io系统调用性能影响

复制100m大小的文件所需要的时间

buf_size总用时总cpu用时用户cpu用时系统cpu用时
1107.43107.328.2099.12
1282.161.590.111.48
40962.050.380.010.38
655352.060.320.000.32
  • 缓冲区大小1个字节时,调用read() wirte()一亿次。
  • 缓冲区大小4096个字节时,需要调用read() write() 24000次左右。
  • 如果缓冲区大小超过4096这个值,性能提升就不会很显著了,因为用户空间和内核空间之间复制数据以及执行实际磁盘IO所花费的时间相比,read 和 write系统调用成本就微不足道了
  • 总之,文件发生大量数据传输时,可以采用大块空间缓冲数据,执行更少的系统调用
13.2 stdio缓冲
  • setvbuf() 控制stdio库使用缓冲的形式
  • fflush() 刷新缓冲区
fflush(stdout);
// 如果stdout是已写打开的文件的指针,则将输出缓冲区的内容写入该指针指向的文件
// 否则清除输出缓冲区
13.3 控制文件io的内核缓冲

强制刷新内核缓冲区到输出文件有时是很有必要的(比如要确保继续操作前将输出真正写入磁盘)

  • fsync() 使缓冲数据和打开fd相关所有元数据刷新到磁盘上
  • fdatasync() 减少对磁盘操作的次数
  • sync() 更新文件信息的所有内核缓冲区刷新到磁盘上

第15章 文件属性

获取文件信息stat()
struct stat
{
    dev_t st_dev; //device 文件的设备编号
    ino_t st_ino; //inode 文件的i-node
    mode_t st_mode; //protection 文件的类型和存取的权限
    nlink_t st_nlink; //number of hard links 连到该文件的硬连接数目, 刚建立的文件值为1.
    uid_t st_uid; //user ID of owner 文件所有者的用户识别码
    gid_t st_gid; //group ID of owner 文件所有者的组识别码
    dev_t st_rdev; //device type 若此文件为装置设备文件, 则为其设备编号
    off_t st_size; //total size, in bytes 文件大小, 以字节计算
    unsigned long st_blksize; //blocksize for filesystem I/O 文件系统的I/O 缓冲区大小.
    unsigned long st_blocks; //number of blocks allocated 占用文件区块的个数, 每一区块大小为512 个字节.
    time_t st_atime; //time of lastaccess 文件最近一次被存取或被执行的时间, 一般只有在用mknod、utime、read、write 与tructate 时改变.
    time_t st_mtime; //time of last modification 文件最后一次被修改的时间, 一般只有在用mknod、utime 和write 时才会改变
    time_t st_ctime; //time of last change i-node 最近一次被更改的时间, 此参数会在文件所有者、组、权限被更改时更新
};
access 检查对文件的访问权限
常量描述
F_OK有这个文件
R_OK有读权限
W_OK有写权限
X_OK有执行权限
更改文件权限 chmod() fchmod()

18章 目录和链接

unlink() 移除一个链接

执行unlink()函数并不一定会真正的删除文件,它先会检查文件系统中此文件的连接数是否为1,如果不是1说明此文件还有其他链接对象,因此只对此文件的连接数进行减1操作。若连接数为1,并且在此时没有任何进程打开该文件,此内容才会真正地被删除掉。在有进程打开此文件的情况下,则暂时不会删除,直到所有打开该文件的进程都结束时文件就会被删除。

rename() 更改文件名
symlink()创建软连接。 readlink()获取软连接所指向的路径名
创建和移除目录 mkdir() rmdir()
移除一个文件或目录 remove()
读目录 opendir() readdir()
文件树遍历 nftw()
进程当前的工作目录 getcwd()
改变进程根目录 chroot()
解析路径名,决定路径。 realpath()
解析路径名字符串 dirname()basename()

第19章 监控文件事件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值