#申请原创# 1 在rt-thread多线程是基操,而且使用方便。
这个状态图如下切换
2 线程管理的主要方法和流程
线程管理是操作系统和并发编程的核心,主要涉及线程的创建、调度、同步和销毁,以提高系统资源利用率和程序执行效率。
2.1. 线程创建
线程可通过以下方式创建:
用户级线程:由用户空间的线程库(如POSIX的pthread)管理,创建开销小,但无法利用多核优势。
内核级线程:由操作系统直接管理,支持多核并行,但创建和切换成本较高。
混合模型:结合两者优势(如Java的线程模型)。
2. 2. 线程调度
操作系统通过调度算法分配CPU时间,常见策略包括:
优先级调度:按线程优先级分配资源。
时间片轮转:每个线程执行固定时间后切换。
多级反馈队列:结合优先级和时间片,动态调整线程队列。
2.3. 线程同步
为避免竞态条件,需同步机制:
互斥锁(Mutex):确保临界区同一时间仅一个线程访问。
信号量(Semaphore):控制资源访问数量。
条件变量(Condition Variable):线程间通信,等待特定条件触发。
2.4. 线程通信
线程间数据共享方式:
共享内存:通过全局变量或堆内存交换数据(需同步)。
消息传递:如管道、消息队列,避免直接共享。
2.5. 线程销毁
线程终止后需释放资源:
主动退出:线程函数执行完毕或调用退出函数(如pthread_exit)。
被动终止:其他线程强制终止(如pthread_cancel),需谨慎避免资源泄漏。
2.6 流程总结
创建:选择线程类型并初始化。
调度:由操作系统分配CPU资源。
执行:运行中通过同步机制协调资源访问。
终止:完成或异常退出后回收资源。
3 根据图纸定义板载的两个灯,分别是PB6和PB7
- /* 定义LED引脚,根据实际硬件修改 */
- #define LED1_PIN GET_PIN(B, 7) // LED1引脚
- #define LED2_PIN GET_PIN(B, 6) // LED1引脚
随后创建两个线程,分别设定时间不同,400ms和600ms的周期,这样会有同步的时候,
- /* LED1线程入口函数 */
- static void led1_thread_entry(void *parameter)
- {
- rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
-
- while (1)
- {
- rt_pin_write(LED1_PIN, PIN_HIGH);
- rt_thread_mdelay(200); // 亮500ms
- rt_pin_write(LED1_PIN, PIN_LOW);
- rt_thread_mdelay(200); // 灭500ms
- }
- }
- /* LED1线程入口函数 */
- static void led2_thread_entry(void *parameter)
- {
- rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT);
-
- while (1)
- {
- rt_pin_write(LED2_PIN, PIN_HIGH);
- rt_thread_mdelay(300); // 亮500ms
- rt_pin_write(LED2_PIN, PIN_LOW);
- rt_thread_mdelay(300); // 灭500ms
- }
- }
最后在主程序中创建线程,并分别启动就可以了
- int main(void)
- {
- /* 创建LED1线程 */
- led1_thread = rt_thread_create("led1",
- led1_thread_entry,
- RT_NULL,
- 512,
- 10,
- 10);
- if (led1_thread != RT_NULL)
- {
- rt_thread_startup(led1_thread);
- }
- /* 创建LED2线程 */
- led2_thread = rt_thread_create("led2",
- led2_thread_entry,
- RT_NULL,
- 512,
- 10,
- 10);
- if (led2_thread != RT_NULL)
- {
- rt_thread_startup(led2_thread);
- }
-
- return RT_EOK;
- }
那么点灯的效果如下
这个点灯的过程虽然浅显,但是快速移植到需要多线程工作的项目。总体来说,还是比freeRTOS更直观,易用。
而且,这个是开源的,移植性很好。在APM32整个系统中都非常容易移植,对应于比较复杂的项目,可以分解成多个简单的任务,再分时执行,开发效率大增。
|