文件IO

您所在的位置:网站首页 无法打开文件以写入,该文件可能被锁定或不可用 文件IO

文件IO

2023-04-01 19:16| 来源: 网络整理| 查看: 265

简述

       io分为标准io和文件io,标准io是基于c库的,可以在多个场景下应用。文件io是包含标准io的,只可以应用在Linux系统之上。

函数

标准io函数          文件io函数

fopen                    open

fread                     read

fwrite                     write

fclose                    close

fseek                     lseek

ftell

标准io里还有几个特殊的函数

fgetc(从文件中读取一个字符到内存中)

fputc(将内存中的一个字符写到文件中)

fgets(从文件中获取一行数据到内存中)

函数的具体用法可以在Linux终端使用man命令查看。

终端(terminal)的原理

 区别:

stdout文件:该文件中没有缓冲,写入的内容立即输出

stderr文件:文件内部里有一个缓冲区,写入的内容不会立即输出(1.遇到了\n  2.缓冲区满了)

任务  进程  程序

程序:是一个存储在硬盘的一个静态文件

进程:是一个正在运行的程序,是动态的

任务:创建进程就是完成任务,一般把进程也称为任务

可以通过 ps - aux命令来查看系统的进程

每个进程系统都会分配一个唯一的id来区别,pid(process id),可以通过getpid()函数来获取进程号

每个进程都会有一个父进程号,ppid(parent pid),可以通过getppid()函数来获取父进程号

可以通过fork()函数来创建自己的子进程

进程的退出:

1.进程退出main函数,一切都结束

2.进程可以调用exit()函数来结束自己,exit函数会结束自己,释放资源,同时向父进程号传递一个数值来表达自己的退出原因。

3.进程可以调用_exit函数来结束自己

exit()                      结束时会清理文件缓存

_exit()                    结束时不会清理文件缓存

僵尸进程:

进程可以调用exit函数来结束自己,释放资源,同时进程会保留一点垃圾在内存中,这就是僵尸进程。留下来的垃圾会由他的父进程来进行收尸,如果父进程先死的话系统会将收尸的任务交给他的爷爷进程,依次推到init进程(进程号=1)

exec函数族:

将进程的内容进行覆盖。

进程间的通信:

1.管道pipe(就是一个特殊的共享文件)

        特点:单向通信,FIFO结构,如果要实现双向通信的话可以创建两个管道文件。

        分为两类:无名管道:被淘汰(只能在父子进程之间进行通信)

                           有名管道:至今还在使用

        特征:1.文件存在内存中,不存在硬盘里(速度快,断电了不存在)

                    2.文件有固定的大小(4kb)

                    3.数据被读走后就会被删除,读取的时候发现没有数据会一直等待数据的写入

                                                                  写入的时候发现写满了,会等数据被读取后再写

2.共享内存

        优点:双向通信,不用数据的拷贝(管道需要拷贝两次)

        缺点:进程同时访问会造成数据的不正确(可以给内存设置标志位来判断哪个进程来进行)

3.信号signal

        Linux进程在收到信号的时候,会中断当前任务的执行,先去执行信号函数的内容,再回来执行剩下的任务。

可以在终端里输入kill -l来查看各种信号

2.SIGINT,就是我们在终端使用了ctrl+c,将进程杀死

3.SIGSEGV(段错误),当进程访问了非法的地址,被系统发现以后,会让程序进行自杀

9.SIGKILL,杀死某个进程    (kill -9 pid)

进程可以修改某个信号的执行内容,当进程收到信号时,可以执行其他的操作。

SIGKILL   SIGTSTP函数不会被修改。

信号的几个应用:1.给子进程收尸

                              2.应用定时器(SIGALRM)

                              3.守护进程(程序要一直执行)

线程:

线程:通信简单    占用空间小(共享空间)        独立性差,安全性低

进程:通信麻烦     占用空间大(开辟新空间)    独立性强,安全性高

并发:

        多个线程同时访问一个资源造成数据的混乱,出错

        我们可以通过给线程上锁来解决并发问题

互斥锁:

首先初始化一把锁:

pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;

访问之前先加锁:

pthread_mutex_lock( &mlock );

访问之后解锁:

pthread_mutex_unlock( &mlock );

原理:线程访问时,发现锁是开着的,就会去加锁,然后运行自己的程序,再把锁解开

当发现锁是锁着的时候,就会一直等待,锁被打开的时候在重复上述的步骤。

分为动态库以及静态库

区别:

动态库:每个程序共享一份(占用空间小)     移植性差      独立性差,依赖性强

静态库:每个程序都有一份(占用空间大)     移植性好      独立性高,依赖性差

制作动态库:

先将库文件的每个.c文件都编译为.o文件(-fPIC,将代码编译为 #地址位置无关#的程序)

gcc media.c  -fPIC  -c -o media.o

 gcc ui.c     -fPIC  -c -o ui.o

再将.o文件进行打包,生成一个动态库   libxx.so

gcc  -shared   *.o   -o libxx.so

 再通过gcc命令(要先将动态库文件放在Linux系统的指定目录下,一般我们放在usr/lib文件下)

gcc main.c   -L 库文件路径    -l 指定库的名字   -o xx.out



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3