工程实践实训日报七
项目名称 【苏嵌实训-嵌入式 linux C 第 7天】
今日进度以及任务 讲解了creat/open/read/write/lseek/close的使用方法,还有线程的概念和基本操作创建和退出等。
本日任务完成情况
动手实现了文件API的相关操作,对文件编程有了更深入的理解,对Linux文件描述符的分配和多任务编程也有了一定的认识。
本日开发中出现的问题汇总 多任务编程的实现操作不熟练。
本日未解决问题 无
本日开发收获 之前对C语言文件部分内容掌握的不是很好,此次趁着实训的机会对文件方面的知识有了一个系统的学习,了解了文件方面的相关操作。同时对多任务编程,实现多任务的方式(进程、线程)有了基本的掌握。
其他 多线程在程序开发中还是应用比较广泛的,但是以前接触比较多的是JAVA、C#中利用多线程进行开发,而利用C语言的多线程进行开发比较少见,本次实训让我对LinuxC语言多线程有了一定的了解。
笔记
1. 嵌入式Linux C的学习
-
嵌入式为什么要移植操作系统?
1、提供软件的移植性;
2、操作系统提供了多任务操作;
3、操作系统提供了丰富的网络协议栈;
4、操作系统将所有设备抽象成文件,方便访问设备.
-
主要学习内容
文件编程、多任务编程(进程、线程)、网络编程
2. 文件编程
-
文件描述符
文件id ----> unsigned int
(知道一个文件描述符,操作这个文件描述符,相当于再操作这个文件)
(文件描述符的分配方式:动态分配(只有当你操作这个文件,系统才会给你分配文件描述符,使用完毕后回收))
(0,1,2这三个文件描述符已经被系统占用,有特殊作用,所以说系统的普通文件id是从3开始的)
-
文件API
creat、open、read、write、lseek、close
//头文件 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //创建一个新文件。creat函数等效于:open(pathname,O_WRONLY | O_CREAT | O_TRUNC, mode), 只能以只写方式打开 int creat (const char *pathname,mode_t mode); //flags参数:O_RDONLY 以只读方式打开文件 // O_WRONLY 以只写方式打开文件 // O_RDWR 以可读写方式打开文件... int open(const char * pathname, int flags); int open(const char * pathname, int flags, mode_t mode); //read()会把参数fd 所指的文件传送count个字节到buf指针所指的内存中。若参数count为0,则read()不会有作用并返回0。返回值为实际读取到的字节数,如果返回0,表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动。 ssize_t read(int fd,void * buf ,size_t count); //write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。当然,文件读写位置也会随之移动。 ssize_t write (int fd,const void * buf,size_t count); //每一个已打开的文件都有一个读写位置, 当打开文件时通常其读写位置是指向文件开头, 若是以附加的方式打开文件(如O_APPEND), 则读写位置会指向文件尾. 当read()或write()时, 读写位置会随之增加,lseek()便是用来控制该文件的读写位置. 参数fildes 为已打开的文件描述词, 参数offset为根据参数whence来移动读写位置的位移数. off_t lseek(int fildes, off_t offset, int whence); //关闭一个已经打开的文件。参数表示需要关闭的文件描述符。该描述符由open或creat函数得到。 int close(int fd);
-
练习:文件操作,写三行数据,读三行数据
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define MAX_SIZE 1024
void read_line(int fd, char *buffer, int max_len)
{
int i;
int ret;
char temp;
for (i = 0; i < max_len; i++)
{
if ((ret = read(fd, &temp, 1)) < 0)
{
perror("read data error!");
return;
}
if (temp == '\n' || ret == 0)
{
break;
}
buffer[i] = temp;
}
buffer[i] = '\0';
}
int main(int argc, char *argv[])
{
int fd;
if ((fd = open(argv[1], O_CREAT | O_RDWR, 0655)) < 0)
{
perror("open file failed!");
exit(1);
}
char buffer[MAX_SIZE];
for (int i = 0; i < 3; i++)
{
memset(buffer, 0, sizeof(buffer));
scanf("%s", buffer);
if (write(fd, buffer, strlen(buffer)) < 0)
{
perror("write data failed!");
exit(1);
}
write(fd, "\n", 1);
}
lseek(fd, 0, SEEK_SET);
for (int i = 0; i < 3; i++)
{
memset(buffer, 0, sizeof(buffer));
read_line(fd, buffer, sizeof(buffer));
printf("%d:%s\n",i + 1,buffer);
}
return 0;
}
3. 多任务编程
-
什么是多任务?
单任务:在一个任务执行期间,其他任务不能被调度
多任务:
单核CPU:存在任务并发,不存在并行
多核CPU:存在并发,也存在并行
-
实现多任务的方式:进程、线程
进程:实现多任务的开销较大,进程间通信效率不高,但安全
线程:实现多任务的开销小,因为线程共享地址空间,所以通信效率高,但不安全