第七部分 Linux系统编程
文章平均质量分 65
本部分讲述编写Linux系统应用层软件常用的一些技术,包括文件IO,标准IO,进程线程操作。
一只流浪小法师
这个作者很懒,什么都没留下…
展开
-
i.MX6ULL终结者线程同步条件变量
条件变量可以说是互斥锁的补充,但不同的是条件变量是用来等待而不是上锁的,当收到条件变量时线程被唤醒,执行到等待函数(pthread_cond_wait)时又阻塞等待条件变量成立。与信号量不同的是,信号量类似于计数器,需要在程序中进行加一减一操作,条件变量有自动置位功能(通过下面实验能体会到);而且条件变量能用一个信号唤醒多个线程。条件变量使用步骤:1.分配条件变量,静态分配将PTHREAD_COND_INITIALIZER赋值给条件变量,动态分配使用pthread_cond_init;2.通知或等待条原创 2021-03-08 18:22:57 · 91 阅读 · 0 评论 -
i.MX6ULL终结者线程同步互斥锁
互斥锁的作用是锁住共享资源,线程在操作共享资源时,保证这个资源不被其他线程改变,锁住的是数据而不是线程。互斥锁保护临界区的方式是只让一个线程持有锁,没有拿到这个锁的线程将会阻塞,即保证临界区的互斥,对共享资源的操作具有原子性。使用互斥机制要避免死锁,死锁产生的情况是:1线程拿着A锁,然后阻塞住想获取B锁,2线程拿着B锁,阻塞想获取A锁,这样两个线程都会阻塞住,等待拿不到的锁,就这样造成死锁,程序不能往下执行。使用互斥锁的步骤:1.在全局区定义互斥锁,静态分配是将PTHREAD_MUTEX_INITI原创 2021-03-06 18:18:27 · 120 阅读 · 0 评论 -
i.MX6ULL终结者线程同步POSIX无名信号量
为保证每个线程对同一资源访问有效,比如一个线程想要从共享资源读数据,而这些资源正在被其他线程修改,那么读出来的数据是无效的,那么就要想办法让其他线程修改完再去读,这时候就用到了同步机制。可以使用Linux系统提供的机制来对线程访问资源的顺序进行同步,本文档挑选了信号量,互斥锁,条件变量来介绍线程同步机制,实验代码在sync/目录下。1 POSIX无名信号量本章介绍POSIX 无名信号量,以下简称信号量。信号量类似于计数器,操作方法和前面的System V 信号灯基本一样。使用信号量的步骤:1.在程序原创 2021-03-05 12:17:56 · 117 阅读 · 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 · 118 阅读 · 0 评论 -
i.MX6ULL终结者线程基础 线程创建
线程是系统调度的基本单位,一个进程中在创建时默认只有一个线程,一个进程可以创建多个线程,这几个线程可以同时执行。多线程比多进程更容易传输数据,由于线程之间能够共享进程里的资源,所以并发线程同时操作进程资源会产出竞争的情况,需要对多线程进行同步操作。如串口需要同时同时收发,应用层可能会因为I/O阻塞阻止程序进行下一步,使用多线程读写可解决问题,即一个线程读,一个线程写,互不影响;在网络编程中可处理多个客户端同时连接和请求。Linux线程和windows中的线程不一样,Linux中的线程是轻量级的进程,但是原创 2021-03-04 17:57:56 · 166 阅读 · 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 · 126 阅读 · 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 · 109 阅读 · 1 评论 -
i.MX6ULL终结者进程间通信 System V共享内存
Linux操作系统的进程通常使用的是虚拟内存,虚拟内存空间是有由物理内存映射而来的。System V 共享内存能够实现让两个或多个进程访问同一段物理内存空间,达到数据交互的效果。 图 1共享内存和其他进程间数据交互方式相比,有以下几个突出特点:1.速度快,因为共享内存不需要内核控制,所以没有系统调用。而且没有向内核拷贝数据的过程,所以效率和前面几个相比是最快的,可以用来进行批量数据的传输,比如图片。2.没有同步机制,需要借助Linux提供其他工具来进行同步,通常使用信号灯。使用共享内存的步骤:原创 2021-03-03 17:42:32 · 129 阅读 · 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通信的步骤为: 图 21.获取 key值,内原创 2021-03-01 10:06:34 · 114 阅读 · 0 评论 -
i.MX6ULL终结者进程间通信信号
信号是非常重要的一种进程通信机制,模拟硬件中断,当某个事件发生后,Linux内核通过发信号通知进程去处理,打断进程的执行,比如在i.mx6ull终结者使用文档/ Linux异步通知实验中就使用了信号机制。信号机制使用一些系统调用在内核注册信号,事件发送后发送信号,进程收到信号后会进行处理,处理方式有以下三种:1.默认方式(通常是终止进程),2.忽略,不进行任何操作。3.捕捉并处理调用信号处理器(回调函数形式)。本章只关注在应用层对信号的处理,如果想进一步体验信号可以在驱动章节体验异步通知。在Ubu原创 2021-03-01 09:57:13 · 92 阅读 · 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 · 96 阅读 · 2 评论 -
i.MX6ULL终结者进程间通信 无名管道
进程间的通信应用也是很广泛的,比如后台进程和GUI界面数据传递,发送信号关机,Ctrl+C终止正在运行的程序等。Linux进程间通信机制分三类:数据交互,同步,信号。理解了这些机制才能灵活运用操作系统提供的IPC工具。本章以常用的管道(包括有名管道和无名管道),System V IPC(消息队列,共享内存,信号灯),套接字(UNIX域套接字和网络套接字)为例来说明Linux进程通信常用的方法,本文档中介绍的只是一小部分,如果想深入了解可以去翻看专业的书籍。本章代码在ipc/文件夹下。1无名管道无名管原创 2021-02-27 09:15:02 · 99 阅读 · 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 · 75 阅读 · 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 · 109 阅读 · 0 评论 -
i.MX6ULL终结者进程基础 进程创建
进程指正在运行的程序,资源分配的最小单位,可以通过“ps ”或“top”等命令查看正在运行的进程,线程是系统的最小调度单位,一个进程可以拥有多个线程,同一进程里的线程可以共享此进程的同一资源。本章代码在process/目录下。进程类型:1.交互进程:由shell启动,用户和计算机进行问答的进程。2.批处理进程:不与特定终端相关联,将任务提交到等待队列按顺序执行的进程。3.守护进程:后台运行的特殊进程,用户不能和它进行会话。进程的三种状态:图 11.运行态,正在运行或在运行队列中等待。2.原创 2021-02-25 15:32:39 · 119 阅读 · 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 · 81 阅读 · 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 · 85 阅读 · 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 · 96 阅读 · 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 · 87 阅读 · 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 · 103 阅读 · 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 · 108 阅读 · 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 · 106 阅读 · 0 评论