
第七部分 Linux系统编程
文章平均质量分 65
本部分讲述编写Linux系统应用层软件常用的一些技术,包括文件IO,标准IO,进程线程操作。
一只流浪小法师
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
i.MX6ULL终结者线程同步条件变量
条件变量可以说是互斥锁的补充,但不同的是条件变量是用来等待而不是上锁的,当收到条件变量时线程被唤醒,执行到等待函数(pthread_cond_wait)时又阻塞等待条件变量成立。与信号量不同的是,信号量类似于计数器,需要在程序中进行加一减一操作,条件变量有自动置位功能(通过下面实验能体会到);而且条件变量能用一个信号唤醒多个线程。 条件变量使用步骤: 1.分配条件变量,静态分配将PTHREAD_COND_INITIALIZER赋值给条件变量,动态分配使用pthread_cond_init; 2.通知或等待条原创 2021-03-08 18:22:57 · 138 阅读 · 0 评论 -
i.MX6ULL终结者线程同步互斥锁
互斥锁的作用是锁住共享资源,线程在操作共享资源时,保证这个资源不被其他线程改变,锁住的是数据而不是线程。 互斥锁保护临界区的方式是只让一个线程持有锁,没有拿到这个锁的线程将会阻塞,即保证临界区的互斥,对共享资源的操作具有原子性。 使用互斥机制要避免死锁,死锁产生的情况是:1线程拿着A锁,然后阻塞住想获取B锁,2线程拿着B锁,阻塞想获取A锁,这样两个线程都会阻塞住,等待拿不到的锁,就这样造成死锁,程序不能往下执行。 使用互斥锁的步骤: 1.在全局区定义互斥锁,静态分配是将PTHREAD_MUTEX_INITI原创 2021-03-06 18:18:27 · 156 阅读 · 0 评论 -
i.MX6ULL终结者线程同步POSIX无名信号量
为保证每个线程对同一资源访问有效,比如一个线程想要从共享资源读数据,而这些资源正在被其他线程修改,那么读出来的数据是无效的,那么就要想办法让其他线程修改完再去读,这时候就用到了同步机制。可以使用Linux系统提供的机制来对线程访问资源的顺序进行同步,本文档挑选了信号量,互斥锁,条件变量来介绍线程同步机制,实验代码在sync/目录下。 1 POSIX无名信号量 本章介绍POSIX 无名信号量,以下简称信号量。信号量类似于计数器,操作方法和前面的System V 信号灯基本一样。 使用信号量的步骤: 1.在程序原创 2021-03-05 12:17:56 · 170 阅读 · 0 评论 -
i.MX6ULL终结者线程基础线程终止与回收
线程终止: 1.start_routine回调函数执行return; 2.线程自身调用pthread_exit(); 3.其他线程调用pthread_cancel(ID)将此进程终止; 任意线程调用exit()使整个进程退出。 线程回收:线程默认joinable状态,终止后需使用pthread_join回收资源;将子线程使用pthread_detach从主线程分离后处于unjoinable状态,系统等线程退出后自动回收资源。 常用的 函数调用如下: pthread_exit():结束本线程 #include原创 2021-03-05 11:47:41 · 165 阅读 · 0 评论 -
i.MX6ULL终结者线程基础 线程创建
线程是系统调度的基本单位,一个进程中在创建时默认只有一个线程,一个进程可以创建多个线程,这几个线程可以同时执行。 多线程比多进程更容易传输数据,由于线程之间能够共享进程里的资源,所以并发线程同时操作进程资源会产出竞争的情况,需要对多线程进行同步操作。如串口需要同时同时收发,应用层可能会因为I/O阻塞阻止程序进行下一步,使用多线程读写可解决问题,即一个线程读,一个线程写,互不影响;在网络编程中可处理多个客户端同时连接和请求。 Linux线程和windows中的线程不一样,Linux中的线程是轻量级的进程,但是原创 2021-03-04 17:57:56 · 211 阅读 · 1 评论 -
i.MX6ULL终结者进程间通信 UNIX域套接字
UNIX域套接字用于进程通信,用法和网络套接字相同,不同的是UNIX域套接字只能在一台机器上的进程之间传输数据,网络套接字可在一台或不同机器之间实现通信。在Ubuntu终端输入“netstat -lx”,可显示所有UNIX套接字连接和监听端口, 图 1 然后输入命令查看udev使用的套接字“ls -l /run/udev/control”, 图 2 文件类型为“s”,表示套接字文件,因为udev是Linux应用层的一个小工具,用来自动识别挂载一些设备,比如U盘等,在开发板的最小系统中没有这个工具原创 2021-03-04 17:51:50 · 163 阅读 · 1 评论 -
i.MX6ULL终结者进程间通信System V信号灯
信号灯也叫信号量,它能够用来同步进程的动作,不能传输数据。它的应用场景就像红绿灯,控制各进程使用共享资源的顺序。Posix无名信号灯用于线程同步, Posix有名信号灯,System V 信号灯。本章讨论用于进程同步的System V信号灯。 信号灯相当于一个值大于或等于0计数器,信号灯值大于0,进程就可以申请资源,信号灯值-1,如果信号灯值为0,一个进程还想对它进行-1,那么这个进程就会阻塞,直到信号灯值大于1。 使用System V信号灯的步骤如下: 1.使用semget()创建或打开一个信号灯集。 2原创 2021-03-03 17:54:23 · 144 阅读 · 1 评论 -
i.MX6ULL终结者进程间通信 System V共享内存
Linux操作系统的进程通常使用的是虚拟内存,虚拟内存空间是有由物理内存映射而来的。System V 共享内存能够实现让两个或多个进程访问同一段物理内存空间,达到数据交互的效果。 图 1 共享内存和其他进程间数据交互方式相比,有以下几个突出特点: 1.速度快,因为共享内存不需要内核控制,所以没有系统调用。而且没有向内核拷贝数据的过程,所以效率和前面几个相比是最快的,可以用来进行批量数据的传输,比如图片。 2.没有同步机制,需要借助Linux提供其他工具来进行同步,通常使用信号灯。 使用共享内存的步骤:原创 2021-03-03 17:42:32 · 181 阅读 · 1 评论 -
i.MX6ULL终结者进程间通信 System V消息队列
System V IPC包含三种进程间通信机制,有消息队列,信号灯(也叫信号量),共享内存。此外还有System V IPC的补充版本POSIX IPC,这两组IPC的通信方法基本一致,本章以System V IPC为例介绍Linux进程通信机制。 可以用命令“ipcs”查看三种IPC,“ipcrm”删除IPC对象。在i.MX6ULL终结者开发板终端输入“ipcs”查看系统中存在的IPC信息: 图 1 这些 IPC对象存在于内核空间,应用层使用IPC通信的步骤为: 图 2 1.获取 key值,内原创 2021-03-01 10:06:34 · 163 阅读 · 0 评论 -
i.MX6ULL终结者进程间通信信号
信号是非常重要的一种进程通信机制,模拟硬件中断,当某个事件发生后,Linux内核通过发信号通知进程去处理,打断进程的执行,比如在i.mx6ull终结者使用文档/ Linux异步通知实验中就使用了信号机制。 信号机制使用一些系统调用在内核注册信号,事件发送后发送信号,进程收到信号后会进行处理,处理方式有以下三种: 1.默认方式(通常是终止进程), 2.忽略,不进行任何操作。 3.捕捉并处理调用信号处理器(回调函数形式)。 本章只关注在应用层对信号的处理,如果想进一步体验信号可以在驱动章节体验异步通知。在Ubu原创 2021-03-01 09:57:13 · 121 阅读 · 0 评论 -
i.MX6ULL终结者进程间通信 有名管道
有名管道在一些专业书籍中叫做命名管道,它的特点: 1.可以使无关联的进程通过fifo文件描述符进行数据传递; 2.单向传输有一个写入端和一个读出端,操作方式和无名管道相同。 mkfifo():创建有名管道使用, #include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode); 参数含义: pathname:有名管道的路径和名称; mode:权限。 返回值:成功返回0,原创 2021-02-27 09:19:29 · 124 阅读 · 2 评论 -
i.MX6ULL终结者进程间通信 无名管道
进程间的通信应用也是很广泛的,比如后台进程和GUI界面数据传递,发送信号关机,Ctrl+C终止正在运行的程序等。 Linux进程间通信机制分三类:数据交互,同步,信号。理解了这些机制才能灵活运用操作系统提供的IPC工具。 本章以常用的管道(包括有名管道和无名管道),System V IPC(消息队列,共享内存,信号灯),套接字(UNIX域套接字和网络套接字)为例来说明Linux进程通信常用的方法,本文档中介绍的只是一小部分,如果想深入了解可以去翻看专业的书籍。本章代码在ipc/文件夹下。 1无名管道 无名管原创 2021-02-27 09:15:02 · 139 阅读 · 0 评论 -
i.MX6ULL终结者进程基础 exec函数族
用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序,该子进程被新的程序替换,改变地址空间,进程映像和一些属性,但是pid号不变。 execve(): #include <unistd.h> int execve(const char *filename, char *const argv[], char *const envp[]); 参数含义: filename:路径名,表示载入进程空间的新程序路径。 argv[]:命令行参数,argv[0]为命令名。 envp[]:原创 2021-02-26 09:26:07 · 132 阅读 · 0 评论 -
i.MX6ULL终结者进程基础 终止与回收
linux的进程终止方式有8种,其中5种是正常终止: 1.从main函数return返回。 2.调用exit函数,exit() 退出的时候会刷新IO缓冲区 3.调用_exit或_Exit。 _exit() 退出的时候不刷新IO缓冲区 4.最后一个线程从其启动例程返回。 5.最后一个线程调用pthread_exit。 异常终止有3种,各自是: 1.调用abort函数。 2.接收到信号并终止。 3.最后一个线程对取消请求做出响应。 其中return和exit的区别是return 返回到调用它的函数,exit退原创 2021-02-26 09:22:08 · 148 阅读 · 0 评论 -
i.MX6ULL终结者进程基础 进程创建
进程指正在运行的程序,资源分配的最小单位,可以通过“ps ”或“top”等命令查看正在运行的进程,线程是系统的最小调度单位,一个进程可以拥有多个线程,同一进程里的线程可以共享此进程的同一资源。本章代码在process/目录下。 进程类型: 1.交互进程:由shell启动,用户和计算机进行问答的进程。 2.批处理进程:不与特定终端相关联,将任务提交到等待队列按顺序执行的进程。 3.守护进程:后台运行的特殊进程,用户不能和它进行会话。 进程的三种状态: 图 1 1.运行态,正在运行或在运行队列中等待。 2.原创 2021-02-25 15:32:39 · 144 阅读 · 0 评论 -
i.MX6ULL终结者文件IO和标准IO 标准IO写文件
fwrite():把 ptr 所指向的数组中的数据写入到给定流 stream 中, #include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 参数含义: ptr:指向内存块的指针; size:每个元素的字节数; nmemb:一次写入的元素个数; stream:打开的 FILE对象的指针。 返回值:成功返回写入元素的个数,如果该数字与nmemb不同会显示错误。 实验代码在fwrite.c原创 2021-02-25 15:10:10 · 107 阅读 · 0 评论 -
i.MX6ULL终结者文件IO和标准IO 标准IO读文件
fgets(): 从文件流中读取一行,并把它存储在 s 所指向的字符串内, #include <stdio.h> char *fgets(char *s, int size, FILE *stream); 参数含义: s:数组指针,读到的字符串储存在此数组内; size:读取的字符数量,通常填写数组长度; stream:打开的文件流。 返回值:读取成功返回与s相同的参数,错误返回一个空指针。 fread():从文件流stream中读nmemb个元素到ptr指向的内存中,每个元素有size个字节。原创 2021-02-24 17:09:40 · 114 阅读 · 0 评论 -
i.MX6ULL终结者文件IO和标准IO 标准IO打开关闭文件流
标准IO使用了缓冲区机制,从而减少系统调用,实现更高的效率,三种缓冲机制为: 全缓冲:当流的缓冲区无数据或无空间时才执行实际I/O操作 行缓冲:当在输入和输出中遇到换行符(‘\n’)时,进行I/O操作。 无缓冲:数据直接写入文件,流不进行缓冲。 常用函数如下: fopen():打开或创建文件流,返回指向该文件流的指针 #include <stdio.h> FILE *fopen(const char *path, const char *mode); 参数含义: filename :字符串,用来原创 2021-02-24 17:03:03 · 121 阅读 · 0 评论 -
i.MX6ULL终结者文件IO和标准IO 获取目录内文件列表
常用函数如下: opendir():打开指定的目录,并返回DIR*形态的目录流, #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); 参数含义: name:路径名字。 返回值:成功返回打开的目录流,失败返回 NULL。 closedir():关闭目录流。 #include <sys/types.h> #include <dirent.h> int closedir原创 2021-02-23 09:37:06 · 117 阅读 · 0 评论 -
i.MX6ULL终结者文件IO和标准IO 文件IO write()
write():常用来写文件,定义如下: #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); 参数含义: fd: 文件描述符; buf: 缓存区,存放将要写入的数据; count: 每次写入的个数。 函数功能: 每次从buf缓存区拿count个字节写入fd文件。 返回值: 大于或等于0表示执行成功,返回写入的字节数; 返回-1代表出错。 实验代码在io/io3.c:路径为:11_Linux系统开发原创 2021-02-23 09:31:31 · 132 阅读 · 0 评论 -
i.MX6ULL终结者文件IO和标准IO 文件IO read()
read():读取文件最常用的函数,定义如下: #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); 参数含义: fd: 要读的文件描述符 buf: 缓冲区,存放读到的内容。 count: 每次读取的字节数 函数功能: 每次从fd读取count个字节,保存到buf中。 返回值: 返回值大于0,表示读取到的字节数; 等于0在阻塞模式下表示到达文件末尾或没有数据可读(EOF),并调用阻塞; 等于-1表示出错,在非阻塞模原创 2021-02-22 11:35:00 · 157 阅读 · 0 评论 -
i.MX6ULL终结者文件IO和标准IO 文件IO open()/close()
文件 IO是Linux系统提供的接口,针对文件和磁盘进行操作,不带缓存机制;标准IO是C语言函数库里的标准I/O模型,在stdio.h中定义,通过缓冲区操作文件,带缓存机制。Linux系统中一切皆文件,包括普通文件,目录,设备文件(不包含网络设备),管道,fifio队列,socket套接字等,在终端输入“ls -l”可查看文件类型和权限。 标准IO和文件IO常用API如下: 1 文件IO open()/close() 本节使用Linux提供的接口来进行打开关闭文件。 open():通过系统调用,可以打开文原创 2021-02-22 11:27:59 · 138 阅读 · 0 评论