UNIX C API¶
1 fork 和 vfork 异同¶
- 执行顺序
fork
:父进程和子进程执行先后顺序不确定,取决于内核调度算法。vfork
:子进程先执行exec
函数簇或exit
,子进程退出再执行父进程。- 内存空间:
fork
:子进程复制父进程的数据空间、堆、栈,共享代码段,子进程改变数据不会响父进程。vfork
:子进程并不完全复制父进程地址空间,子进程与父进程共享数据空间,子进程改变数据会影响父进程。vfork
目的是创建一个新进程,再让新进程通过 exec 函数簇去执行一个新程序。
title: 写时复制技术(copy on write)
由于在fork之后,往往子进程直接使用exec函数簇去执行另一段代码,不需要使用到父进程的数据段、堆栈,复制这些不使用的区域会导致不必要的开销,写时复制技术可以解决此类问题。
当任意一个进程修改了这些数据时,则内核才为这块数据分配一个地址,制作一个副本。
1.1 wait 和 waitpid 异同¶
wait
使其调用者阻塞,waitpid
由参数控制是否阻塞。
2 解析命令行参数¶
2.1 getopt 获取命令行参数¶
- 功能:解析命令行参数
- 语法:
int getopt(int argc, char * const argv[],const char *optstring);
argc
:main 函数的 argcargv
:main 函数的 argvoptstring
: 解析的选项字母,且最后需尾随冒号:
(选项以-
加字母的短选项组合,后再接一个长选项,如./test -n 1 -t 2
,optstring 则设置成nt:
)- 返回值:解析到参数返回短选项,解析到不存在的选项返回冒号
:
,解析完返回 -1 - 示例
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int flags, opt;
int nsecs, tfnd;
nsecs = 0;
tfnd = 0;
flags = 0;
while ((opt = getopt(argc, argv, "nt:")) != -1)
{
switch (opt)
{
case 'n':
flags = 1;
break;
case 't':
nsecs = atoi(optarg);
tfnd = 1;
break;
default: /* '?' */
fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
argv[0]);
exit(EXIT_FAILURE);
}
}
printf("flags=%d; tfnd=%d; optind=%d\n", flags, tfnd, optind);
if (optind >= argc)
{
fprintf(stderr, "Expected argument after options\n");
exit(EXIT_FAILURE);
}
printf("name argument = %s\n", argv[optind]);
/* Other code omitted */
exit(EXIT_SUCCESS);
}
- 输出结果
$ ./test_getopt -t 123 -n 567
flags=1; tfnd=1; optind=4
name argument = 567
2.2 getopt_long¶
3 flock,lockf,fcntl¶
https://www.cnblogs.com/starrysky77/p/9974130.html
- flock 对应 fuse flock
- lockf 对应 fuse lock
4 fallocate¶
- 使用场景:需要生成大文件时, 使用 fallocate 可以替代 dd 功能。
4.1 fallocate 和 truncate 有所区别¶
fallocate
:为文件预分配物理空间,不是生成空洞文件,而且 fallocate 分配的空间在磁盘的扇区上是连续的,能减少后续写入和读取文件时的磁盘寻道的资源开销truncate
:生成的是空洞文件,并不占用实际的磁盘空间, 只是文件看上去逻辑大小比较大,但实际占用的空间是 0。
4.2 什么是空洞文件¶
UNIX 的文件操作,允许操作的偏移位置超过当前的文件长度,这样中间留出的空间的字节会被设置为 0,这部分空间被称为空洞 (hole),linux 系统上空洞不占用实际的硬盘空间。