您的位置:首页 > 理论基础 > 计算机网络

linux C学习第二天之应用编程和网络编程笔记(上)

2016-10-31 12:31 591 查看
1、C语言中不能再一个函数里面定义别的函数  。所以没有局部函数

2、const int a=5;   int const a=5;  两者意义一样 该变量a的值是个常量,不能改变

  const int *p;  

 int const *p ; 

const 在*前面表示指向的数据是个常量,指针可以改变

int * const p;

const int *const p;

const 在*后面的表示指向的指针是个常量,值不一定是个常量

一、文件描述符 :出了当前进程就没有意义了

   1、关于man命令的使用

    man 1 xxx  查shell命令 

  man 2 xxx 查API

man 3 xxx查库函数

2、我们如何退出程序

  (1)在main中return  如果程序正常运行,正常返回 return 0,如果异常退出 则return -1;

 (2)   (1)不算是比较常规的退出进程方法  ,正式终止进程  应该使用 exit()  _exit()    _Exit()

 

关于exit()和_exit()

  exit()函数定义在stdlib.h中,而_exit()定义在unistd.h中

简单的说,exit函数将终止调用进程。在退出程序之前,所有文件关闭,缓冲输出内容将刷新定义

_exit终止调用进程,但不关闭文件,不清除输出缓存,也不调用出口函数

3、阻塞与非阻塞(关于open时候的flag  O_NONBLOCK)

  (1)如果一个函数是阻塞的,则我们调用这个函数时进程有可能被卡住(阻塞住,实质是该函数执行的条件未成熟,没法执行,得等待时机成熟)

  (2)如果一个函数是非阻塞的,我们调用该函数时,该函数会立即返回,但是否完成任务不一定。

    (3)阻塞与非阻塞是两种不同的设计思路,并没有好坏。总的来说,阻塞式的结果有保障,但时间没保障。非阻塞式的时间有保障但结果没保障。

(4)操作系统的API或者由API封装成的库函数 有很多本身就是被设计为阻塞式或者非阻塞式的。所以我们应用程序调用这些函数时一定要非常清楚。

(5)我们打开文件的时候默认的是阻塞式的,如果你希望以非阻塞的方式打开文件,则flag中要加O_NONBLOCK方式打开文件。

(6)阻塞与非阻塞只用于设备文件,不用与普通文件

4、O_SYNC

  (1)WRITE 阻塞等待底层将缓冲区数据写回硬盘 才返回应用层

 (2)无O_SYNC时 只是将内容写进缓冲区即返回。。

(二)、文件读写的一些细节

   1、errno   其实就是error number linux操作系统给各种常见错误编号,当函数执行错误时,函数会返回一个特定的错误编号errno 告诉我们到底哪里错了。

 2、errno 是OS维护的一个全局变量,任何OS内部函数都可以通过设置errno来告诉上层调用者究竟发生了一个什么错误。

3、errno本身是一个int类型的数字,比如-37,每个不同的错误号对应一个错误信息,linux系统提供了一个函数perror  来输出错误信息。错误信息不用我们提供,直接在出错位置perror("打开文件错误"); //perror()里面是一个字符串

(三)、read和write的 count 参数 

  1、count  是我们想要读或者写的字节数目 

    返回值是实际完成的我们要写的或者读的字节数,可能等于要读写的字节数或者小于(未完成)

2、当读写和阻塞非阻塞联合事情就更复杂了。 如果一个函数是阻塞的,我们要读30字节,目前只有20个字节,则读取20个字节时就会阻塞等待剩余的10个字节。

3、要读写的文件很大的时候 应该设置一个合适的一次读写的count数目,循环读写 而不应该一次性读写完

(四)、文件IO效率和标准IO

   1、文件IO是指当前所说的open write read 等 API 函数构成的一套用来读写文件的体系 这套体系可疑很好的读写文件但是效率有些低。

  2、应用层C语言库提供了一些用来读写文件的函数列表,叫做标准IO,标准IO 由一系列的库函数构成,(f_open,f_close,f_read,f_write),这些标准IO其实是由文件IO封装而成的,(比如f_open内部还是调用了open.)标准IO加了封装主要是为了在应用层增加一个缓冲机制,这样我们通过f_write函数写的内容并不是直接进入内核buf中,而是先进入应用层标准IO库维护的buf中,然后标准IO根据操作系统单词write的最佳count选择最佳的时机来完成write到内核buf中(内核再根据最好的时机去将buf数据写到磁盘上)

(五)linux如何管理文件

   1、快速格式化和底层格式化 :

    快速格式化:速度很快 ,比如格式化一个32G硬盘只需要1秒   底层格式化比较慢

  两者的差别:快速格式化只是删除了inode信息,并没有删除数据,有可能还原格式化后的硬盘。 底层格式化则是将数据删除了,基本上是不可能还原数据的。

2、文件与流

     (1)流(stream)  文件读出或者写入时只能一个字符一个字符的操作,这样就够成了一个流。

(2)流这个概念是动态的,不是静态的

(3)编程中提到的流是与IO相关的,所以叫IO流。文件操作时就构成一个IO流。

3、lseek

  当打开一个空文件时,默认情况是文件指针指向文件流开始,所以这时候去write是从文件开头写的。

 write 和 read函数值自带移动文件指针。如果读写NGe字节,则文件指针后移N个字节

如果想要随意移动文件指针 则需使用lseek

  *****当调用lseek移动文件指针之后,再去调用read和write函数则从移动后的文件指针开始。

4、stdin stdout stderr 对应描述符是0 ,1 , 2标准输入 标准输出 标准错误

   printf 默认输出到标准输出   fprintf则可以指定输出到那个文件描述符中

 int printf(const char *format, ...);

       int fprintf(FILE *stream, const char *format, ...);

(六)文件共享的问题

1、文件多次打开

     普通文件可以被重复打开  重复打开一个相同的文件。两个不同的fd,对其读写 是分别读和分别写

如果希望是接续写读  则 在open时候flag 时候|O_APPEND   为什么加O_APPEND就可以接续写呢 关键核心是文件指针

 http://edu.csdn.net/course/detail/2401/37561?auto_start=1      第九课   文件重复打开

2、何为文件共享

     (1)文件共享就是,同一个文件(同一个文件即同一个inode,相同的路径名)被多个独立的读写体(可以理解为多个文件描述符)去同时(一个文件打开但是尚未关闭就去执行另一个操作)操作。

  (2)文件共享的意义有很多:比如我们可以通过多线程同时去操作一个大文件,提高读写效率。

3、文件共享的核心是如何弄出来多个文件描述符指向同一个文件

   常见的方法有三种:(1)同一个进程多次使用open打开同一个文件(fd不相同)。。(2)是在不同的进程中去使用open打开同一个文件(两个进程的fd有可能相同有可能不同) (3)linux 内核提供了一个API   dup()和 dup2()让进程复制文件描述符(dup复制文件描述符,但是赋值出来的fd2是与fd1不同的,只是复制了一份fd1d的描述符表。所以两个fd对应的相同的文件指针,因此dup 和dup2其实只能接续读写)

  我们关注文件共享时是关心文件读写是分别读写还是接续写

*************父进程创建的子进程退出后,父进程没有回收子进程的结束信息时,子进程就便成一个僵尸进程,因此档一个父进程调用fork函数创建一个子进程而不调用wait函数时,一个僵尸进程就诞生了。

***************当父进程在子进程之前结束运行,这时该子进程就成为孤儿进程,linux系统由init进程负责领养所有的孤儿进程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 文件IO
相关文章推荐