Linux多进程之间的通信(一)
概念关键进程通信:在用户空间实现进程通信是不可能的,通过Linux内核通信线程间通信:可以在用户空间就可以实现,可以通过全局变量通信。
方式管道通信:无名管道、有名管道(文件系统中有名,文件系统)信号通信:信号(通知)通信包括:信号的发送、信号的接收和信号的处理。IPC(Inter-Process Communication)通信:共享内存、消息队列和信号灯。以上是单机模式下的进程通信(只有一个L加ux内核)Socket通信:存在于一个网络中两个进程之间的通信(两个Linux内核)。
通信实现的思想
基于文件IO理念
open:功能:创建或打开进程通信对象。函数形式不一样,有的是有多个函数完成。write:功能:向进程通信对象中写入内容。函数形式可能不一样。read:功能:从进程通信对象中读取内容。函数形式可能不一样。close:功能:关闭或删除进程通信对象。形式可能不一样。
管道通信原理
管道文件是一个特殊的文件,是由队列来实现的。
无名管道12#include <unistd.h>int pipe(int pipefd[2]);
水从高处流 The array p ...
信号通信fork函数
一、fork 后的父子进程由 fork 创建的新进程被称为子进程(child process)。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是 0,而父进程的返回值则是新进程(子进程)的进程 id。将子进程 id 返回给父进程的理由是:因为一个进程的子进程可以多于一个,没有一个函数使一个进程可以获得其所有子进程的进程 id。对子进程来说,之所以 fork 返回 0 给它,是因为它随时可以调用 getpid() 来获取自己的 pid;也可以调用 getppid() 来获取父进程的 id。(进程 id 0 总是由交换进程使用,所以一个子进程的进程 id 不可能为 0)。
fork 之后,**操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这 2 个进程共享代码空间,但是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置**(两进程的程序计数器 pc 值相同,也就是说,子进程是从 fork 返回处开始执行的),但有一点不同,如果 fork 成功,子进程中 for ...
Linux多线程
概念
进程:一个正在执行的程序,它是资源分配的最小单位进程中的事情需要按照一定的顺序透个进行,那么如何让一个进程中的一些事情同时执行?线程
线程:有时又称轻里级进程,程序执行的最小单位,系统独立调度和分派cu的基本单位,它是进程中的一个实体。一个进程中可以有多中线程,这些线程共享进程的所有资源,线程本身只包含一点必不可少的资源。进程出现了很多弊端,一是由于进程是资源拥有者,创建、微消与切换存在较大的时空开销,因此需要引入轻型进程:二是由于对称多处理机(SMP)出现,可以满足多个运行单位,而多个进程并行开销过大。
并发是指在同一时刻,只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。看起来同时发生,实际上单核内轮询执行。
并行是指在同一时刻,有多条指令在多个处理器上同时执行。真正的同时发生
同步:彼比有依赖关系的调用不应该“同时发生”,而同步就是要阻止那些“同时发生”的事情
异步的解念和同步相对,任何两个彼此独立的操作是异步的,它表明事情独立的发生
主线程
当c程序运行时,首先运行main函数。在统程代码中,这个特殊的执行流被 ...
Linux基础之文件系统
文件系统功能
能定义文件的组织方式,文件结构
提供建立和存取文件的环境:目录和文件
能对文件存储器空间进行组织和分配
负责文件存储并对存入的文件进行保护和检索
负责建立文件,存入、读出、修改、转储文件,控制文件的存取,撤销文件等
文件系统分类
磁盘文件系:NTFS,EXT3
闪存文件系统,JFFS2,YAFFS
数据库文件系统,BFFS,WINFS
网络文件系统:NFS
虚拟文件系统,VFS(Proc)
Linux文件系统EXT3
EXT3是基于日志方式的文件系统
系统中每个文件都是有索引,
用户对对文件的每一个操作都会记录日志,
形成一个任务队列排着执行
性能是比较好
SWAPswap是交换分区的文件系统,类似windows的虚拟内存虚拟内存的实现:两种方式
第一种是进行内存的排列像内存池一样,进行一个优化
第二种是把硬盘上的空间模拟成内存swap是Linux的虚拟内存,在安装时要设好大小,是物理内存的2倍
Linux与Window目录结构的区别
根目录Linux:/Windows:\
命名写区分Linux:命名区分大小写;Windows:命名不区分大小写
结构管理Linu ...
C语言之编译
编译过程
define include 不是关键字,他们在预编译的时候就被替代了。
常见编译错误
预处理错误
#include”file.h“ 默认先从当前路径中寻找,找不到再从系统环境中查找。#include<file.h> 直接从系统环境中寻找
NOT FIND 注意自己创建用双引号。解决方法:可以通过相对路径;通过写入头文件路径的方式。
2. 链接错误 原材料不够或者溢出。
缺少原材料
原材料溢出
原因是链接重复的函数。
预处理的使用
#include 包含头文件
#define 宏,替换 预处理时不进行检查直接进行替换,在编译时才进行检查
#define 宏名 宏体 为了避免错误,加括号
123456//错误例子#define ADD35 3+5printf("%d",ADD35 *5); //3+5*5=28//正确例子#define ADD35 (3+5)printf("%d",ADD35 *5); //(3+5)*5=40
系统预定义宏
5. 条件宏变量
多用于 ...
C语言之函数的使用
字符空间与非字符空间的区别
函数地址传址嵌入式中对于单个值进行修改的可以使用int *,char *,long *。如果传递的是空间则默认为void *。
指针指向的合法性
即函数中的局部变量在函数指向完会被清除,如果直接return局部变量会造成指针异常。
合法空间:非局部变量,即非栈空间变量。static,常量,堆区(malloc,free)
C语言之内存的操作
c语言格式符合
const 修饰符
volatile 修饰防止内存优化,每次从地址读值
typedef 别名
指针运算操作
指针运算:p+n取得的是地址,p[n]取出的是内容,值
内存越界
c语言存在内存越界,c++并不存在
值比较
多级指针的例子
数组的初始化
字符串末尾默认加‘\0’
编译器只有第一次赋值可以一次性解决,以后对于数组操作,只能逐一操作,即一位一位进行修改。
字符拷贝的问题
字符拷贝函数的原贝则:内存空间和内存空间的逐一赋值的功能的一个封装体一旦空间中出现了0这个特殊值,函数就即将结束。
strcpy()函数存在问题,如果destination值后面没有’\0’,则会一直拷贝。工程中尽量不用。
strncpy可以设置拷贝字符长度,避免内存泄漏。
字符空间
内存拷贝
二维数组
结构体中字节对齐
即空间换效率,采取最大字节单位进行对其,所以空间大小都为4的倍数
代码编码后的地址位置
一般系统(ARM,x86等)的代码地址位于低地址
x86:一般为于0x8084..
内存空间结构
只读空间:静态空间,整个程序结束时释放内存,生存周期最长栈空 ...
基于ESP32S3的FreeRTOS之事件组(五)
事件组等待
设置事件组大小,如果宏定义USE_16_BIT_TICKS设置为1则,事件组大小为8;如果为0则为24位。
事件组同
事件组等待的执行逻辑
事件组同步的执行逻辑
code
基于ESP32S3的FreeRTOS之定时器(四)
Software Timer 软件定时器
基于Daemon Task,定时器任务通过定时器命令队列进行发送给执行指令,然后任务调用相应的程序,执行软件定时器的回调函数。
软件定时器的特点
不受硬件影响,不受MCU的影响
软件定时器的数量与堆栈,TIMER_TASK_STACK_DEPTH的影响。不受影响影响
创建并启动定时器
延时并停止
获取Timer名字
获取一个Timer ID
基于ESP32S3的FreeRTOS之信号量(六)
Binary Semaphore 二进制信号
使用信号量执行任务
创建信号量之后为了使用它必须要释放它。
创建信号量并调用任务
任务一进行调用使用信号量
任务二调用使用信号量
结果
未使用信号量呢
结果
计数信号量
创建任务
使用计数信号量,最大信号量减减
释放信号量
结果
互斥量 mutex
这块需要反复理解
创建信号量,挂起任务调度器,创建执行任务,开启任务调度器
主要是优先级的继承,task1继承了task3所以可以执行任务
task3优先级最高首先运行,发生阻塞后task2开始执行,task2发生阻塞,task1开始执行,获取信号量并锁定。由于task3的优先级高,所以task3开始执行,然而信号量依旧在task1那,并未被释放task1超出时间片,看门狗被触发,idle任务因为要用于内存的清理回收,idle任务无法执行,就会触发看门狗。所以task3尝试取信号量,尝试失败后进入task2while循环,循环超时触发看门狗,然后task继续3尝试获取信号量。以此反复。
...