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

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

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

一、标准I/O编程

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

1、3种缓冲存储

  (1)全缓冲:当填满标准 I/O 缓存后才进行实际I/O 操作。存放在磁盘上的文件通常是由标准I/O 库实施全缓冲的。在一个流上执行第一次I/O 操作时,通常调用malloc()就是使用全缓冲。

  (2)行缓冲:当在输入和输出中遇到行结束符时,标准 I/O 库执行I/O 操作。标准输入(scanf())和标准输出(read())使用的就是行缓冲。

  (3)不带缓冲:标准 I/O 库不对字符进行缓冲。如果用标准I/O 函数写若干字符到不带缓冲的流中,则相当于用系统调用write()函数将这些字符全写到被打开的文件上。

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

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

(一)fopen()

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

  (1)函数原型:FILE * fopen(const char * path, const char * mode)
  (2)函数参数:

参数含义
path包含要打开的文件路径及文件名
mode文件打开状态

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

参数作用
r/rb打开只读文件,该文件必须存在
r+/r+b打开可读写的文件,该文件必须存在
w/wb打开只写文件,若文件存在则文件长度清为0,即会擦写文件以前的内容。若文件不存在则创建该文件
w+/w+b打开可读写文件,若文件存在则文件长度清为0,即会擦写文件以前的内容。若文件不存在则创建该文件
a/ab以附加的方式打开只写文件。若文件不存在,则会创建该文件;如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留
a+/a+b以附加方式打开可读写的文件。若文件不创建,则会建立该文件;如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留

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

(二)fclose()

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

  (1)函数原型:int fclose(FILE * stream)
  (2)函数参数:

参数含义
stream已打开的文件指针

  (3)函数返回值
    成功:0
    失败:EOF

(三)fwrite()

该函数数用于对指定的文件流进行写操作。

  (1)函数原型:size_t fwrite(const void * ptr,size_t size, size_t nmemb, FILE * stream)
  (2)函数参数:

参数含义
ptr存放写入记录的缓冲区
size写入的记录大小
nmemb写入的记录数
stream要写入的文件流

  (3)函数返回值
    成功:返回实际写入的记录数目
    失败:EOF

(四)fread()

在文件流被打开之后,该函数可对文件流进行读写等操作,其中读操作

  (1)函数原型:size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)
  (2)函数参数:

参数含义
ptr存放读入记录的缓冲区
size读取的记录大小
nmemb读取的记录数
stream要读取的文件流

  (3)函数返回值
    成功:返回实际读取到的 nmemb 数目
    失败:EOF

二、Linux进程

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

1、进程的运行状态

进程有三种运行状态,分别为等待、就绪和执行,它们的转换关系如下:
1150471-20170521215936103-177467589.png

2、Linux下进程管理

可用Shell命令对进程进行简单的管理操作,最常用的命令如下:

命令含义
ls等shell命令启动相应的进程
ps查看系统中的进程
ps -ef查看正在活动的进程
top动态显示系统中的进程(q退出)

3、Linux进程控制编程

(一)fork()

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

  (1)函数所需头文件:sys/types.h、unistd.h
  (2)函数原型:pid_t fork(void)
  (3)函数返回值:

返回值含义
0子进程
子进程ID(大于0的整数)父进程
-1出错

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

(二)exec族函数

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

  (1)函数所需头文件:unistd.h
  (2)函数原型:

函数名函数原型
execlpint execlp(const char file, const char arg, ...)
execlint execl(const char path, const char arg, ...)
execleint execle(const char path, const char arg, ..., char *const envp[])
execveint execve(const char path, char const argv[], char *const envp[])

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

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

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

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

(三)终止进程函数

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

(四)中断进程函数

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

  (1)函数所需头文件:sys/types.h、sys/wait.h
  (2)函数原型:

函数名函数原型
wait()pid_t wait(int *status)
waitpid()pid_t waitpid(pid_t pid, int *status, int options)

  (3)函数参数:
wait():status 是一个整型指针,是该子进程退出时的状态,status 若不为空,则通过它可以获得子进程的结束状态。

waitpid():

Pid
    pid>0        只等待进程ID 等于pid 的子进程,不管已经有其他子进程运行结束退出了,只要指定的子进程还没有结束,waitpid()就会一直等下去
    pid=1        等待任何一个子进程退出,此时和wait()作用一样
    pid=0        等待其组ID 等于调用进程的组ID 的任一子进程
    pid<1        等待其组ID 等于pid 的绝对值的任一子进程
    
status           若不为空,则通过它可以获得子进程的结束状态

options
    WNOHANG        若由pid 指定的子进程不立即可用,则waitpid()不阻塞,此时返回值为0
    WUNTRACED      若实现某支持作业控制,则由pid 指定的任一子进程状态已暂停,且其状态自暂停以来还未报告过,则返回其状态
    0              同wait(),阻塞父进程,等待子进程退出

  (4)函数返回值:
wait():
    成功:已结束运行的子进程的进程号
    失败:1

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

三、收获与感悟

(1)更加深入的理解了C语言对文件操作的原理及过程,体会到了标准I/O处理(fopen()、fread()等)相对于系统调用(open()、read())的简便性。
(2)加深了对进程的理解,掌握了一系列对进程错做的函数。
(3)结合wait()和waitpid()的实例,加深了对多种缓冲区的理解。
(4)学会了新的markdown语法。

四、学习进度条

代码行数(新增/累积)博客量(新增/累积)学习时间(新增/累积)重要成长
目标5000行30篇400小时
第一周200/2002/220/20
第二周300/5002/418/38
第三周500/10003/722/60
第四周300/13002/930/90
第五周700/20003/1260/150

五、参考资料

  • 《嵌入式应用程序设计》学习指导

转载于:https://www.cnblogs.com/lingzhoulingyu/p/6886293.html

CCF大数据与计算智能大赛-面向电信行业存量用户的智能套餐个性化匹配模型联通赛-复赛第二名-【多分类,embedding】.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值