文件操作:创建,删除,打开关闭,编辑,保存,拷贝,剪切
系统提供了很多函数,如strcmp strcpy等等。我们使用这些函数完成我们需要的功能即可
应用程序----c库----操作系统----硬件 磁盘(文件)
操作文件:把文件放在硬盘中,修改时调用内存(读),在内存中完成修改后,返回到硬件中(写)。
程序的传参:
使用方法:编译命令格式
编译:gcc 文件名.c -o 自定义命令名字.out
运行:./自定义命令名字.out 参数一 参数二等等
Fgetc每次读取一个数据
Fputc每次写入一个数据
文件的访问位置:
文件的连续读写,是如何实现的:文件内部都有一个指针整数记录当前位置,开始位置,open时为pos=0;fread fwrite函数都会修改指针
我们可以主动调整指针位置;
- 获取当前位置:int pos=ftell(fp) printf(“%d”,pos)
(2)修改位置:int fseek(文件指针,偏移量(offset),相对于那个位置的参照物(whence))
Whence:SEEK_SET,offset相对于头部文件
SEEK_END,offset尾部
SEEK_CUR,offset当前位置
读取文件尾部10个字符
Fseek(fp,-10,SEEK_END)
获取系统函数出错的具体原因:
Printf(“errno:%d\n”,errno)errno是全局变量,系统自带,不需要声明,但是需要添加头文件#include<errno.h>
Errno返回的是一个整数,需要查表对应找出错误,可以用strerror(errno)函数打印出对应的问题,或者perror(“”)直接打印错误原因。
通过写读文件实现printf和scanf函数功能:
1 stdout 文件内部有个缓冲区,printf写入的内容并不会立即刷新到屏幕上,遇到\n立即刷新到屏幕上。
2 stderr 文件内部没有缓冲区
程序存储在硬盘中,是静态文件,进程存储在内存中,是动态文件
所有的进程都是init进程的子孙
查看进程 ps -aux
创建自己的子进程:
Fork (克隆)产生新的进程。会在内存中分配一片空间然后将父亲的所有东西,全部拷贝到新的空间,包括程序执行位置。(相互不影响)
进程的退出:
Exit(i)进程退出main函数,一切结束会清理文件缓存。建议使用这个
_Exit(i)结束进程时,不会清理文件缓存
僵尸进程:
进程调用exit()结束自己,释放自己的资源,但是进程会保留一点垃圾在内存中,这个时刻,称为僵尸进程,父进程来清理垃圾
子进程调用exit()结束自己,同时传递一个整数,
父进程获取子进程的退出码(i)
int pid(孩子pid) =wait(&i)
缺点需要父进程一直等待
32位二进制
>>8 & 0xFF(右移八位二进制再与00000000000011111111相与操作)
进程间通信:
原理:进程跑在系统之上,他们可以看到同一个系统。那么在系统中分配一片共享区域,两个进程都可以访问。
- 管道文件(mkfifo)
- 通过一个读一个写文件,存在于内存中,断点数据丢失文件有固定大小(4kb)
- 读写特性:数据读走就删除,如果读取时候发现没有数据,则read函数阻塞等待(直到有数据。如果write函数数据过多,buf写满了,write函数阻塞等待,直到读走删除数据)
Tmp临时文件夹
共享内存:
在系统中,创建一片共享的内存空间,多个进程都可以看见该空间,有点没有拷贝数据,双向通信
同一时刻只能一个人去访问,不然会出现问题,使用一个标志位
0表示无数据,1有数据。要为0才可以写,写满了就变为1,要为1时才读,读完了就变为0
信号signal:
Linux进程支持信号操作:进程在执行过程中,收到信号,先处理信号再回来继续执行
访问了一片非法的地址,就会出现段错误,segment fault、core dump
如何发送信号:
- 快捷键 Ctrl +c Ctrl+z
- 命令:kill -信号id 进程pid
信号的应用:
1:给子进程收尸 当子进程死亡时主动给父进程发送信号,就不会让父进程一直傻傻等待
子进程exit时就会发送信号给父进程,17 SIGCHLD 父进程修改该信号的处理方法。
2:定时器 原理:进程能够定时发送信号和收到信号SIGALRM,那么就能实现定时功能。
Alarm(3)3秒后发送信号
3:守护进程,一直执行
进程需要在后台一直运行,但是终端关掉,进程结束。
因为关闭终端时进程会发送信号让其自杀,所以修改发送命令则可以实现一直运行。杀掉程序时用kill -9 pid号。当然还可以:使用nohup ./a.out命令执行程序,程序会忽略SIGHUP命令。
哪些信号不能被捕获呢?
SIGKILL kill -9 pid 是可以随时杀死程序
SIGTSTP Ctrl +z
(共享资源的进程)线程:共享空间不需要进行通信,一个程序中有两个执行体,节约了内存。
函数Pthread _create
库的使用:
如何制作动态库:
1.将库文件的各个.c编译为.o
Gcc xx.c -fPIC -c -o xx.o
2.将.o打包,生成一个动态库 libxxx.so
Gcc -shared *.o -o libxxx.so
- 使用者
Gcc main.c -L 库文件路径 -l 指定库名字 -o xx.out
前提:将我们的动态库放入Linux系统中的指定目录下
静态库:每个程序都有一份,浪费内存 独立性强,独自执行
(共享库)动态库:共享,只有一份, 需要严重依赖对应的库文件
线程的睡眠和唤醒:
Pthread _cond_wait()睡眠
Pthread_cond_signal()唤醒