分类 - C语言

2016-08-02 11:41:24    203    0    0

1.缓冲
FILE * 类型的函数或者以此为返回值的都是有缓冲区的
1.全缓冲
2.行缓冲 例如:标准输出【stdout】
3.无缓冲 例如:标准出错【stderr】

说明:c语言的关于文件操作的函数,其实都是使用了unix 内核的函数,而这些内核的函数全都是没有缓冲区的,但是,c语言在调用这些内核函数生成库函数的时候都加了缓冲区

2.一般的系统,在进程启动是,默认打开三个文件,
stdin 标准输入
stdout 标准输出
stderr 标准出错
其中标准出错和标准输出都是输出到终端上面

3.stdout [标准输出]的刷新方法:
1.遇到\n
2.调用了fflush(stdout) fclose(stdout) 这些函数
3.调用了标准的输入函数: getchar() gets() 等等这些函数
4.当一个进程结束,也会自动的刷新缓冲区

4.函数:
1. FILE * fopen(const char * path, const char *mode);
path:打开的文件路径 【这里支持绝对路径也支持相对路径】
mode:打开的方式:
r 只读 r+ 读写 文件的读写位置在文件的开头
w 只写 w+ 读写 文件的读写位置在文件的开头
a 追加写 a+ 读写 文件的读写位置在文件的结尾

返回值,我们叫做文件的句柄
2. size_t fread(void * ptr, size_t size, size_t nmemb, FILE *stream);
ptr: 就是要把数据读到哪里,我们一般定义一个buf
size:一次要读多少字节
nmemb:读几次
stream:要读那个文件的句柄
3. size_t fwrite(void * ptr, size_t size, size_t nmemb, FILE *stream);

ptr: 我们要从哪里读数据
size:一次要读多少字节
nmemb:读几次
stream:要写入的那个文件的句柄
4. fclose(FILE * fd);
fd 要关闭的文件描述符。
5.int fseek(FILE *fd, long offset, int whence);
【说明】 此函数实现对文件的句柄进行定位,当我们打开一个文件的时候,文件的描述符默认
实在文件最开始,文件的描述符指向哪里,那么接下来的对文件的操作就是从这里开始的。
fd: 文件描述符
offse

2016-08-02 11:46:18    191    0    0

 

网络通信 总结:

1.不管是UDP还是TCP通信,基本的过程都是,首先建立链接,然后发送消息,然后对方接受消息。
2.网络通信的模式,的书写方法都是固定的,不管是UDP还是TCP。写法固定。
3.网络通信的比较重要的部分是通信报文的设计,下面详解:

网络通信报文的书写

1.报文的两种的组织形式。
1.使用结构体的方法: 定义好各种类型的消息结构体,然后在发送消息的时候,对结构体对象的里面的成员进行
相应的赋值,在接受方,就收消息,使用同样类型的结构体,然后对消息里面的各种数据
成员进行解析,在处理。使用这种方式处理,简单,容易处理。
2.使用消息组合的方法:就是把要发送的消息的内容,按一定的序列进行组合,说实在的就是拼接在一起,在拼接的时候使用一些标识符进行分隔。
然后发送,在接受端,接受消息以后,要对消息按照和发送端相反的顺序进行分解,从而得到具体的消息的指令或者是请求


网络通信的服务器的类型:
1.循环服务器
就是服务器会循环的接受,客户端或者是发送端的各种请求然后处理,但是他永远只是单个线程在处理,当有个客户端没有断开链接的时候
其他的客户端无法进行链接。

2.多进程,多线程服务器

显然就是多个线程。多个进程同时的进行操作,和处理客户端的请求,
其实这个也有多种方法。
1.一种就是属于被动的等待,来一个链接请求,我就创建一个进程或者是线程,但是计算机,允许创建的进程的个数是有限的。
2.一种就是主动的事先创建好一定数量的线程,或者是进程,你来一个请求我就调用一个线程,当你的个数多于我已经创建的个数,那就等待
这就涉及到线程池的概念。


2016-08-02 11:46:41    164    0    0


进程
1.进程就是CPU处理事务的一个过程
2.一个进程独占一段内存空间,独占CPU

进程的开始:
1.对于一个C程序,从main 函数开始,或者是从fork()函数开始
进程的创建:
1.对于整个的OS,init 进程是自举 其他进程都由其父进程创建
说明:init进程是在系统开始的时候自己创建出来的进程 也是第一个进程
其进程ID是 1.
进程的结束:
1.正常结束:从main函数结束, 或者是调用了exit()族函数
2,异常结束:有信号终止

exit() 和_exit() 函数的区别:
1._exit()函数直接进入内核,结束进程
2.exit()函数是先进行一些必要的处理操作,然后在进入内存
处理操作:1.关闭未关闭的文件 2.关闭进程的终止处理函数
进程终止处理函数:就是在进程结束是会自动调用的函数。
注册一个终止处理函数:使用 atexit()
int atexit(void (*function)(void));
参数就是一个函数指针。

执行的时候,是先注册的后运行,后注册的先运行


进程id
在OS中,一个进程有一个唯一的进程ID,来标识该进程
类型是pid_t
查看当前OS运行的进程使用命令:#ps


查看进程id的一些函数:
getpid(); 获取当前进程的id
getppid(); 获取父进程的id
getpgid(); 获取当前进程的组id
getsid(); 获取会话id
getuid(); 获取执行当前进程的用户id
getgid(); 获取执行当前进程的用户的组id

 

进程的创建:
函数:pid_t fork(void);

1.被创建的子进程继承父进程的地址空间,包括栈,堆, 静态区 代码段等
2. fork函数执行一次,返回两次,子进程返回 0 父进程返回 子进程的ID
3.父子进程的执行的先后的顺序是由系统调度决定的。
4.虽然子进程拷贝了父进程的地址空间,但是父子进程对这段内存空间是独占的
5.对于文件描述符,子进程相当于是dup了父进程的描述符
父子进程关闭文件描述符,对别的进程没有影响 因为是独占的,父子进程共享fork前
打开的描述符的偏移量

 

孤儿进程:
父进程结束但是子进程还没有结束。我们把这样的进程叫做孤儿进程
在linux下面,所有的孤儿进程都会被init进程收养,也就是说,所有的孤儿进程的
ppid都是 1.
僵尸进程:
子进程已经结束,但是父进程没有为其收