Part11 -- Arduino如何实现多线程(SCoop)
1 简介
1、多线程是什么?为什么要用多线程?
进程 :是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程中的一个独立控制单元,线程在控制着进程的执行。一个进程中至少有一个线程。
多线程:一个进程中不只有一个线程。是指从软件或者硬件上实现多个线程并发执行的技术。
2、为什么要用多线程?
-
为了更好的利用cpu的资源,如果只有一个线程,则第二个任务必须等到第一个任务结束后才能进行,如果使用多线程则在主线程执行任务的同时可以执行其他任务,而不需要等待; 进程之间不能共享数据,线程可以; 系统创建进程需要为该进程重新分配系统资源,创建线程代价比较小;
在Arduino实际开发中,我们可能会遇到多任务处理的问题,Arduino需要不断的读取外部管脚所输入的传感器数值;同时,要产生PWM方波来控制步进电机;如果有上位机,则还需要完成数据的收发工作。
针对此类多任务同时处理的工作场景,解决方法有多种,第一:使用计时器或外部中断机制,完成多任务处理;第二:使用Arduino 多线程技术,本质上也是中断机制。
Arduino开发板借助SCoop即可轻松实现多线程。
2 使用方法
GitHub链接下载此文件,Arduino IDE 中选择 项目 → 加载库 → 添加一个 .ZIP库 ,然后找到刚才压缩的SCoop.zip文件,添加完成之后就可以使用了。GitHub下载地址:
第一步,引用库文件
#include "SCoop.h"
第二步,setup函数里,调用 mySCoop.start() 命令
void setup(){ mySCoop.start(); }
第三步,loop函数里,调用 yield() 命令
void loop(){ yield(); }
第四步,定义线程并实现具体的功能,有两种定义方式 (1)完整定义
定义一个名字为“TaskOne”的任务
defineTask(TaskOne); void TaskOne::setup(){ // 初始化 } void TaskOne::loop(){ // 执行的任务 }
(2)快速定义
如果线程中执行的动作不需要setup的话,还可以使用defineTaskLoop快速定义的方式,如下:
defineTaskLoop(TaskTwo){ // 实现具体的功能 }
注意: 使用此库之后,如果只是想在某个线程中暂停,请使用sleep(ms) 作为延时,因为 sleep(ms) 只针对当前线程,而 delay(ms) 是针对全局的。
3 测试代码
/********************************************************************* ——————1.开发环境:Arduino IDE———————————————————————————————————————— ——————2.使用开发板型号:Arduino UNO—————————————————————————————————— ——————3.功能:2个LED分别以0.5秒和1秒的速度闪烁,2和3引脚分别接LED—————— *********************************************************************/ #include <SCoop.h> # define LED1 2 // 初始化引脚 #define LED2 3 defineTask(TaskOne); // 创建子线程1 defineTask(TaskTwo); // 创建子线程2 void TaskOne::setup(){ // 线程1设定 pinMode(LED1,OUTPUT) } void TaskOne::loop(){ //线程1循环 digitalWrite(LED1,HIGH); sleep(500); digitalWrite(LED1,LOW); sleep(500); } void TaskTwo::setup(){ //线程2设定 pinMode(LED2,OUTPUT) } void TaskTwo::loop(){ //线程2循环 digitalWrite(LED2,HIGH); sleep(1000); digitalWrite(LED2,LOW); sleep(1000); } void setup(){ mySCoop.start(); } void loop(){ yield(); }
Arduino虽然可以实现并发处理,但最多只能支持两三个并发任务,再多就可能报错了,如果还想处理更多并发任务,推荐用 stm32。
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
多线程互斥锁Lock和RLock区别