2014025679 《嵌入式系统程序设计》第五周学习总结

本周主要在上周学习的基本的C语言文件操作函数的基础上,学习了标准I/O编程。另外,还学习了Linux操作系统的进程及其控制编程相关的知识。

一、标准I/O编程

write()、read() 等这些函数是接本的 I/O 控制,没有缓存,系统调用是操作系统直接提供的函数接口,因此运行系统调用时,过程非常繁琐,Linux 必须从用户态切换到内核态,执行相应的请求,然后再返回到用户态。而标准 I/O 处理与之相比优势在于拥有缓存,减少系统调用的次数,从而提高程序的效率。

1、基本操作标准 I/O 编程函数

对文件进行基本操作最常用的函数便是 fopen()、fclose()、fwrite()和fread()四个函数了, 在调用它们前必须引入 stdio.h 头文件,以下便是它们的函数原型、参数机返回值。

(1)fopen()

该函数可以指定打开文件的路径和模式。

FILE * fopen(const char * path, const char * mode)打开文件的访问权限等,可选参数如下(在每个选项中加入 b 字符用来告诉函数库打开的文件为二进制文件):

  函数返回值:
    成功:指向 FILE 的指针
    失败:NULL

(2)fclose()

该函数可以将缓冲区内的数据全部写入到文件中,并释放系统所提供的文件
资源。

int fclose(FILE * stream)

    成功:0
    失败:EO

(3)fwrite()

该函数数用于对指定的文件流进行写操作:size_t fwrite(const void * ptr,size_t size, size_t nmemb, FILE * stream)

   函数返回值
    成功:返回实际写入的记录数目
    失败:ERORR

(4)fread()

在文件流被打开之后,该函数可对文件流进行读写等操作,其中读操作size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)

成功:返回实际读取到的 nmemb 数目失败:ERORR.

二、Linux进程

进程:是一个程序的一次执行的过程,同时也是源分配的最小单元。进程与程序的区别在于进程是动态的,而程序是静态的。

1、进程的运行状态

进程有三种运行状态,分别为等待、就绪和执行.

2、Linux进程控制编程

(1)fork()

fork()函数用于从已存在的进程中创建一个新进程。新进程成为子进程,原进程为父进程。因为子进程为父进程的复制品,所以子进程除了独有的进程号、资源使用和计时器等,其余的全部与父进程一致。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main(){
pid_t result;
result=fork();
if(result == -1){
printf("Fork error!");
}
else if(result == 0){
printf("The returned value is %d\n In child process!!!\nMy PID is %d\n",result,getpid());
}
else{
printf("The returned value is %d\n In father process!!!\nMy PID is %d\n",result,getpid());

}
return 0;
}

(2)exec族函数注意:
  (1)父进程的返回值则是新进程(子进程)的进程 id。将子进程id返回给父进程的理由是:因为一个进程的子进程可以多于一个,没有一个函数使一个进程可以获得其所有子进程的进程id。

exec族函数提供了启动fork()创建的子进程的方法,有多个成员函数。

  函数所需头文件:unistd.h
  函数返回值:

    -1:出错
  (4)成员函数说明:
execlp():使用文件名在环境变量$PATH中查找可执行文件,同时使用参数列表的方式启动子进程。

execl():使用完整的文件目录来查找对应的可执行文件启动子进程,文件目录开头必须使用根目录(/)。

execle():可将环境变量添加到新建的子进程中,并启动子进程。

execve():可以通过构造指针数组的方式向子进程传递参数,并启动子进程。

(3)终止进程函数

想要终止进程时,可以调用exit(0和_exit()两个函数,它们都可以令进程会无条件地停止剩下的所有操作,清除包括PCB 在内的各种数据结构,并终止本进程的运行。在参数方面一般使用0(表示正常结束)。但它们也有些不同之处:
exit():需要引入头文件stdlib.h,它在调用exit 系统之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,也就是能将缓冲区中的信息保存或输出等操作。
_exit(0:需要引入头文件unistd.h,调用时不会检查缓冲区,直接终止进程,并清空I/O缓冲区,也就是会令缓冲区中的信息丢失。(printf()实用的是行缓冲,在没有\n的情况下,会将当前这一行的信息存入缓冲区中,不会输出)

(4)中断进程函数

由于CPU同时只能执行一个进程,有时就需要中断现在的进程,为其他进程提供CPU执行的条件,就需要调用wait()或waitpid()函数。

函数所需头文件:sys/types.h、sys/wait.h

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
printf("PID = %d\n",getpid());
printf("PPID = %d\n",getppid());
return 0;
}

函数参数:

wait():status 是一个整型指针,是该子进程退出时的状态.

wait():使父进程(也就是调用wait()的进程)阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。如果该父进程没有子进程或者他的子进程已经结束,则wait()就会立即返回。
waitpid():在wait()的基础上,拥有更多的选项参数,可以实现更多的功能,可以认为wait()是waitpid()的特例。

三、收获与感悟

    更加深入的理解了C语言对文件操作的原理及过程,了解到了标准I/O处理(fopen()、fread()等)相对于系统调用(open()、read())的简便性。了解对进程的理解,结合wait()和waitpid()的实例,理解了多种缓冲区。

posted on 2017-05-23 22:10  邴成德  阅读(169)  评论(0编辑  收藏  举报