悟云

let it be

0%

你的城市没有一扇窗,为我打开啊。
我要卖掉我的房子,浪迹天涯。

之前几次的面试经历中好几次面试官都问过程序运行时在main函数之前发生了些什么。 笔者大概知道是做一些初始化相关的事情,今日详细mark一下。
main函数执行之前,主要就是初始化系统相关资源:
1.设置栈指针
2.初始化static静态和global全局变量,即data段的内容
3.将未初始化部分的赋初值:数值型short,int,long等为0,bool为FALSE,指针为NULL,等等,即.bss段的内容
4.运行全局构造器,估计是C++中构造函数之类的吧
5.将main函数的参数,argc,argv等传递给main函数,然后才真正运行main函数
同样地,main函数结束之后就是一些资源释放的事情,以及调用之前注册的终止处理程序等等。
附上一段apue上注册终止程序的demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "apue.h"
static void my_exit1(void);
static void my_exit2(void);
int main(void)
{
if(atexit(my_exit2) != 0){
err_sys("can't register my_exit2");
}

if(atexit(my_exit1) != 0){
err_sys("can't register my_exit1");
}

if(atexit(my_exit1) != 0){
err_sys("can't register my_exit1");
}

printf("main is done\n");
return 0;
}

static void my_exit1(void)
{
printf("first exit handler\n");
}

static void my_exit2(void)
{
printf("second exit handler\n");
}

超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,也被称为HTTP over TLS,HTTP over SSL或HTTP Secure)是一种网络安全传输协议。在计算机网络上,HTTPS经由超文本传输协议进行通信,但利用SSL/TLS来对数据包进行加密。HTTPS开发的主要目的,是提供对网络服务器的身份认证,保护交换数据的隐私与完整性。
之前就听说过ssl,但是觉得比较鸡肋,所以开始也没准备折腾。后来看到谷歌宣布从2017年一月开始正式将http页面标记为不安全,看来这是大势所趋。
参照这篇博文折腾了一番。

Unix对于每个文件维护了3个时间字段,它们的意义如下图所示:

很多影响到i节点的操作,如更改文件的访问权限、更改用户id、更改链接数等,但它们并没有更改文件的实际内容。因为i节点中的所有信息都是与文件的实际内容分开存放的。

POSIX(Portable Operating System Interface)修改文件的访问时间和修改时间

1
2
3
#include <sys/stat.h>
int futimens(int fd, const struct timespec times[2]);
int utimensat(int fd, const char * path, const struct timespec times[2], int flag);

Single UNIX Specification的XSI扩展

1
int utimes(const char * pathname, const struct timeval times[2]);

笔者曾经写过一个爬虫,里面涉及到一些临时文件的操作。在解析页面时总会有各种各样的异常导致临时文件删除失败。如今对Unix文件系统有了一些更为深入的理解,这个问题也迎刃而解。
Unix文件系统中有个非常重要的概念,i节点。文件系统中的每个目录项都会指向一个i节点,每个i节点中都有一个链接计数,其值是指向该i节点的目录项数。只有当链接计数减少至0时,才可删除文件(也就是释放该文件占用的数据块).另一个条件也会阻止删除文件的内容——只要有进程打开了该文件,其内容也不会删除。
关闭一个文件时,内核首先检查打开该文件的进程个数;如果这个计数达到0,内核再去检查其链接计数;如果计数也是0,那么就删除该文件的内容。
这意味着我们可以在创建一个临时文件的时候就调用unlink函数,程序结束之后(无论是正常还是异常结束)临时文件都会被删除。

原子操作指的是由多步组成的一个操作。如果该操作原子地执行,则要么执行完所有步骤,要么一步也不执行,不可能只执行所有步骤的一个子集。
关于原子操作的概念和定义很早以前都知道了,但是对于其底层实现细节却知之不详。
今天看到一篇不错的文章,参见这里