自制智能指针

实现自动隐式转换

template <typename U>
smart_ptr(smart_ptr<U>&& other)
{
	ptr = other.release();
}

注意这个构造函数不被编译器视作移动构造函数,不触发删除拷贝构造函数

shared_ptr需要维护一个计数块的指针

调用了构造函数还是复制构造函数

回归到它们的参数,那个引用上去

右值引用绑定到右值,常左值引用绑定到左值

std::move表达式的值类别为xvalue,后续资料还没查到(只查到了prvalue绑定的preference),猜测是会被prefer绑定到右值引用版本

prvalue绑定到引用上,有延长生命周期,但是xvalue没有

result&& r = std::move(return_rval()); //💥

线程id只在所属的进程中有意义

进程时间

时钟时间

wall clock time 真实世界的总运行时间,受系统中所有因素的影响

用户时间 执行用户指令

系统时间 执行系统服务

用户时间+系统时间=CPU时间<时钟时间

进程控制系统调用(fork、exec 和 wait)通常由用户应用程序直接调用(请回忆图 1-7中的基本 shell)。但是为了简化某些常见的情况,UNIX 系统也提供了一些库函数,如 system和popen。

malloc不一样,是对sbrk的复杂封装

O_SYNC 使每次write等待物理I/O操作完成,包括由该write操作引起的文件属性(如修改时间)更新所需的I/O。

O_RSYNC 使每一个以文件描述符作为参数进行的read操作等待,直至所有对文件同一部分挂起的写操作都完成。

由open和openat函数返回的文件描述符一定是最小的未用描述符数值。

openat函数是POSIX.1最新版本中新增的一类函数之一,希望解决两个问题。

第一,让线程可以使用相对路径名打开目录中的文件,而不再只能打开当前工作目录。在第 11 章我们会看到,同一进程中的所有线程共享相同的当前工作目录,因此很难让同一进程的多个不同线程在同一时间工作在不同的目录中。

第二,可以避免time-of-check-to-time-of-use(TOCTTOU)错误。

at 系列函数的逻辑可以简化为:

  1. 如果路径是绝对路径,直接使用该路径。
  2. 如果路径是相对路径:
    • 如果 dirfdAT_FDCWD,则使用当前工作目录。
    • 否则,使用 dirfd 所指向的目录作为基准。

原子操作

open O_EXCL | O_CREAT

测试并打开,确保调用open的进程就是创建文件的进程

pread pwrite

定位并读写

dup和fcntl

打开任一类型的文件时,对路径名中包含的每一个目录,包括它可能隐含的当前工作目录都应具有执行权限。这就是为什么对于目录其执行权限位常被称为搜索位的原因。

在某个目录创建/删除文件时,都需要对目录有写和执行权限。

标准IO库

提供了流的抽象,配置了缓冲来减少read/write的调用。

流可分为单字节和多字节的,可通过fwide查看,一旦设置完成除了freopen无法更改。

流的缓冲形式

1.全缓冲 磁盘文件

2.行缓冲 终端

3.不带缓冲 stderr

可以在打开一个流,并在对他进行其他操作之前,使用setbuf系列函数重新设置缓冲类型。

fgetc/fputc保证是一个函数,getc/putc可能是宏

允许回送字符到缓冲区中,读入顺序与压回顺序相反

c语言字符数组是在栈上的,字符串指针指向的字符串字符串常量是在只读区的。

mkstemp会尝试修改字符串内容,如果使用的是字符串常量会segment fault。

内存流

没有底层文件

匿名文件流 字符串流

malloc 初始值不确定

calloc 批量申请内存,保证全0

realloc 调整分配内存大小

alloca可以在栈上申请内存,通过改变栈指针实现

不要在函数参数列表中使用alloca

不需要手动释放(栈空间的性质)