2 UNIX环境高级编程
2.1 unix基础
字符和字符串
-
字符用单引号,字符字面量就是字符(就是ASCII对应字符),是整数
-
字符串用双引号,字符串字面量就是字符指针,是字符首地址
字符数组和字符指针
char *str = "This is a string.";
char string[ ]="This is a string.";
#str是一个变量,可以使其指向不同字符串,但不能改变其指向的字符串常量
#string是一个数组,可以改变其数组中保存的内容,但不能改变其地址
标准C
- 先有ISO C (也叫ANSI C, libc,即标准C),然后有POSIX C,和GNU C (glibc)
可变参列表
https://www.runoob.com/cprogramming/c-standard-library-stdarg-h.html
2.2 文件和目录
文件
- 侧重于内核和文件描述符,不带缓冲
- 对应底层IO函数,fcntl.h(文件控制库)和unistd.h(符号常量库)
打开关闭:create open close
读写:write read
移动:lseek
复制:dup dup2
改变fd属性:fcntl (O_NONBLOCK设置非阻塞IO)
目录
-
目录也是个文件,结点保存下层文件的inode编号
-
DIR结构相当于目录的fd,是内部结构
-
dirent结构里保存文件名d_name
mkdir opendir readdir
2.3 文件流
文件流
- 流是指文件中存储的数据流向设备,侧重于用户空间,带缓冲
- 文件描述符和缓冲区指针位于FILE结构体内
- 对应标准IO函数,最终调用底层IO,因为有缓冲更快,stdio.h(标准IO库)
缓冲:setbuf setvbuf (_IOFBF _IOLBF _IONBF)
打开关闭:fopen fclose
读写流:getc fgetc getchar putc fgetc putchar
每次一行:gets fgets puts fputs
二进制IO:fread fwrite
移动:fseek
格式化IO:printf fprintf sprintf snprintf vprintf
转换:fdopen fileno
临时文件:tmpnam tmpfile
文件流重定向
-
所谓重定向,就是改变文件流的源头或目的地,eg.显示器改为文件。
-
freopen用于文件流的的重定向,一般是将 stdin、stdout 和 stderr 重定向到文件
-
linux管道符本质上是将一个命令的stdout重定向到另一个命令的stdin
2.4 时间和日期
time获取时间戳
localtime转化为当地时间
strftime将本地时间转化为格式化字符串
strptime将格式化字符串转化为本地时间
2.5 进程环境
所有程序在退出时都会调用exit函数
atexit用来登记终止处理程序
environ是全局二级指针,用来指向环境向量表
stdlib.h定义通用工具函数
getenv setenv
2.6 进程控制
- 0号进程idle,系统进程
- 1号进程init,用户进程,所有进程都来自于1号进程
- 僵死进程:子进程退出,父进程存在,并且未通过wait或者waitpid捕获状态和释放资源
- 孤儿进程:父进程退出,子进程会被init进程收养
- fork进程时会通过写时复制来为子进程创建一个堆栈和数据区的副本,之后除了txt段外不共享任何内存区,同样会复制一份文件描述符表,并共享同一文件偏移量
- fork子进程后,父进程应该调用wait/waitpid或者忽略/处理SIGCHLD信号,避免僵死进程
fork:复制进程,调用一次,返回两次
vfork:不复制地址空间,并且优先调度子进程,保证执行exec
wait:阻塞等待子进程返回
waitpid(-1, NULL, 0):非阻塞等待以及指定pid,设为WNOHANG时并且返回0表示子进程未exit
exec函数族:用来将另一个可执行程序替换当前的进程,内存全部替换,通常用execl
system函数:执行cmd字符串,内部由fork和execl(/bin/sh)组成
2.7 进程关系
-
进程组:用于批量接收信号
-
会话:多个进程组的集合,通常会话的领头进程是shell,也称控制进程
-
会话通常和一个控制终端连接,获取输入和信号
-
退出会话或者退出头进程,内核会给会话内其它进程发送SIGHUP挂起,通过nohup忽略
-
守护进程:daemon(),运行在后台的持续进程,无终端,父进程是init,终端符&
2.8 信号
- 信号是软件中断,是进程间通信机制中唯一的异步通信机制
signal:挂钩信号处理
kill -USR1 7216:发出信号
abort:发出SIGKILL信号
alarm:定时函数,到时间就发送SIGALRM信号,默认处理是终止,可signal挂钩
pause:使调用进程挂起,直到捕捉到信号
2.9 线程控制
- 线程控制:https://blog.csdn.net/qq_22847457/article/details/89371217
- 线程同步:https://blog.csdn.net/u022812849/article/details/109225200
结构:pthread_t
获取ID:pthread_self
创建线程:pthread_creat
退出:pthread_exit
等待:pthread_join
分离:pthread_detach
2.10 高级IO
select poll epoll
2.11 进程间通信
管道
- 管道也是一种文件,分为匿名管道和命名管道
- 管道是单向阻塞的
- 利用匿名管道和dup2可以编写协同进程,让子进程的标准输入和输出来自父进程
匿名管道:pipe popen pclose
命名管道:mkfifo (类似创建文件)
设置管道容量:fcntl (F_SETPIPE_SZ)