SoC如何实现线程安全?

原创 美男子玩编程 2024-12-15 08:00

点击上方蓝色字体,关注我们

在 SoC上实现线程安全是多线程编程中非常关键的一个问题,特别是当涉及资源共享时。


线程安全的设计目的是避免多个线程同时访问共享资源时出现竞争条件、数据竞争等问题。


1


线程栈(Thread Stack)

在多线程系统中,每个线程都有自己独立的栈,用于存储局部变量、函数调用的返回地址等。


栈的独立性是线程安全的基础之一,因为栈是线程私有的,不会与其他线程共享。


因此,所有存储在栈上的数据,比如局部变量、函数参数等,默认是线程安全的。


细节分析:

  • 栈的分配SoC 上的多核处理器或多线程操作系统(如 Linux、RTOS)为每个线程分配独立的栈。在 Cortex-M 系列的 ARM 处理器上,栈指针(SP)用于跟踪每个线程的栈顶位置。每个线程的栈是从操作系统堆栈池或系统内存中分配的。

  • 中断和线程栈在实时操作系统中,如果在中断期间发生线程切换,处理器需要保存当前线程的栈指针,并加载下一个线程的栈指针。这一过程称为“上下文切换”,它依赖于栈的独立性以确保线程安全。


以下示例中local_var 是局部变量,位于栈中,因此不同线程各自拥有自己的 local_var,不会造成资源竞争。


void thread_function() {int local_var = 0; // 局部变量保存在当前线程的栈中local_var += 1;printf("Thread local variable: %d\n", local_var);}

2


可重入函数(Reentrant Function)

可重入函数是指多个线程可以同时调用而不会引发竞争条件的函数。


为了实现可重入,函数必须:

  1. 不使用静态数据(除非有线程安全的保护机制)。

  2. 不依赖共享资源,或者对共享资源进行保护(如通过锁定机制)。

  3. 不返回指向静态或全局数据的指针。


细节分析:

  • 静态变量的危险性静态变量在全局内存中分配,所有线程共享该变量,因此多个线程同时访问或修改静态变量时会导致数据竞争。如果需要使用静态数据,必须通过锁或其他同步机制来保护它。

  • 递归函数问题递归函数需要特别注意,如果递归函数使用全局或静态数据,那么它在不同线程递归调用时就会出现问题。


以下示例中non_reentrant_function 中的 static_var 是共享的,多个线程访问时会产生竞态条件;而 reentrant_function 仅使用局部变量,是线程安全的。


int non_reentrant_function(int a) {    static int static_var = 0;  // 静态变量导致线程不安全    static_var += a;    return static_var;}
int reentrant_function(int a, int b) { return a + b; // 不使用任何共享资源,线程安全}

3


线程安全函数(Thread-Safe Function)

为了让函数在并发环境下是线程安全的,常用的方式是使用同步机制来保护共享资源。


典型的同步机制包括:

  • 互斥锁(Mutex)防止多个线程同时访问共享资源。

  • 读写锁(Read-Write Lock)允许多个线程同时读,但写操作是排他的。

  • 信号量(Semaphore)控制访问共享资源的线程数量。

  • 自旋锁(Spinlock)当需要保护的代码执行时间很短时,使用自旋锁可以避免线程休眠,提高效率。


细节分析:

  • 互斥锁的开销在资源竞争较少的情况下,互斥锁可能会导致性能下降,特别是在 SoC 系统上,因为线程切换和上下文切换的开销较大。在嵌入式系统中,自旋锁有时会被用来代替互斥锁,以减少因线程休眠带来的额外开销。

  • 自旋锁的使用场景自旋锁适用于在多核处理器上,线程在短时间内可以完成任务而不需要休眠的场景。自旋锁会让线程忙等待,直到获取锁,但会消耗 CPU 资源。


以下示例通过 pthread_mutex_lock 和 pthread_mutex_unlock 对共享变量 shared_resource 进行加锁和解锁操作,确保只有一个线程可以在同一时间修改 shared_resource。


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int shared_resource = 0;
void* thread_safe_function(void* arg) { pthread_mutex_lock(&mutex); // 加锁保护共享资源 shared_resource += 1; printf("Shared resource: %d\n", shared_resource); pthread_mutex_unlock(&mutex); // 解锁 return NULL;}

4


一次性初始化(One-Time Initialization)

在多线程环境中,有时某个共享资源或全局变量只需要初始化一次,比如一个全局配置或共享对象。


为了确保初始化操作的线程安全,可以使用 pthread_once 来保证只初始化一次。


细节分析:

  • 双重检查锁定(Double-Checked Locking)为了减少加锁开销,有时会使用双重检查锁定,先检查是否已经初始化,如果没有再加锁并初始化。双重检查锁定是为了避免不必要的锁定开销,特别是在初始化后频繁读取全局变量的场景中。

  • 内存屏障问题在某些多核处理器上,编译器和 CPU 可能会重排指令,导致初始化操作和赋值顺序不一致。为了解决这个问题,内存屏障可以确保在多核系统中操作的顺序一致。


以下示例pthread_once 确保无论有多少个线程,initialize_resource 函数都只会被调用一次,保证了线程安全的初始化。


pthread_once_t once_control = PTHREAD_ONCE_INIT;
void initialize_resource() { printf("Resource initialized.\n");}
void* thread_function(void* arg) { pthread_once(&once_control, initialize_resource); // 保证初始化只发生一次 printf("Thread is running.\n"); return NULL;}

5


线程特有数据(Thread-Specific Data)

线程特有数据(Thread-Specific Data, TSD)允许每个线程拥有自己的数据副本,而这些数据不会被其他线程访问。


可以使用 pthread_key_create、pthread_setspecific 和 pthread_getspecific 来管理线程特有数据。


每个线程都有独立的存储空间来保存它的特有数据,因此不会引发竞态条件。


细节分析:

  • 线程局部存储的工作原理在实现上,TSD 通常使用哈希表或数组进行存储,每个线程都有自己的独立副本,操作系统或线程库负责在上下文切换时保存和恢复线程的特有数据。

  • 销毁线程特有数据当线程退出时,应该确保特有数据得到适当销毁。这通常可以通过设置销毁函数(destructor)来自动释放资源。


以下示例每个线程都通过 pthread_setspecific 设置自己的特有数据,并通过 pthread_getspecific 获取数据,保证了每个线程的数据是独立的,线程安全。


pthread_key_t tls_key;
void destructor(void* value) { free(value); // 销毁线程特定的数据}
void* thread_function(void* arg) { int* thread_data = (int*)malloc(sizeof(int)); *thread_data = 1; pthread_setspecific(tls_key, thread_data); // 设置当前线程的特有数据
printf("Thread-specific data: %d\n", *(int*)pthread_getspecific(tls_key)); return NULL;}
int main() { pthread_key_create(&tls_key, destructor); // 创建 TLS key 并设置销毁函数
pthread_t thread1, thread2; pthread_create(&thread1, NULL, thread_function, NULL); pthread_create(&thread2, NULL, thread_function, NULL);
pthread_join(thread1, NULL); pthread_join(thread2, NULL);
pthread_key_delete(tls_key); // 删除 TLS key return 0;}

6


线程局部存储(Thread Local Storage, TLS)

线程局部存储是一种更方便的方式,允许每个线程有一组私有的全局变量副本,避免多个线程之间的共享。


大多数编译器提供了内置支持,例如在 GCC 中,__thread 关键字可以用于声明线程局部变量。


细节分析:

  • TLS 的实现机制在 SoC 系统或嵌入式操作系统中,TLS 通常通过 CPU 的上下文切换机制来实现。每个线程的上下文不仅包括寄存器,还包括 TLS 的数据段。TLS 的数据结构通常存储在线程控制块(Thread Control Block, TCB)中,每个线程拥有独立的 TCB。


以下示例__thread 关键字声明的 tls_var 是线程局部变量,每个线程都有自己的副本,因此是线程安全的。


__thread int tls_var = 0;
void* thread_function(void* arg) { tls_var += 1; printf("TLS variable: %d\n", tls_var); return NULL;}


SoC 上的线程安全设计需要在多个层面加以考虑,从栈隔离到复杂的同步机制(如互斥锁、信号量等),不同机制有不同的应用场景。


线程特有数据和 TLS 提供了更灵活的数据管理方式,使得每个线程能够独立存储和访问它的特有数据,避免数据竞争问题。

点击阅读原文,更精彩~

美男子玩编程 多领域、有深度的开发者交流平台
评论
  • 霍尔传感器的原理        霍尔传感器是一种固体的传感器,其输出电压与磁场强度成比例。顾名思 义,这种器件是依赖于霍尔效应原理工作的。霍尔效应原理是在导体通电 和加有磁场的情况下,在导体的横向 上会产生电压。电子(在实践中多数载流子最常被使 用)在外部电场的驱动下会产生“漂移”,当暴露于磁场中时,这些运动 的带电粒子会受到一个垂直于电场和 磁场的力的作用。这个力会让导体的边缘充电,一边为正,一边为负。边
    锦正茂科技 2024-12-14 11:41 41浏览
  • 2023年,艾迈斯欧司朗正式推出专为自适应远光灯(ADB)与投影式头灯设计的首代EVIYOS®多像素LED,为驾驶者夜间行车带来了全新体验。EVIYOS®这一前沿技术已率先被应用于大众汽车的途锐与途观车型中,这些车型的头灯系统由马瑞利精心打造,每套系统均集成19,200个精密像素点,而EVIYOS®光源模块自身则可集成多达25,600个独立可控像素点。基于EVIYOS®技术的智能头灯大大提高夜间道路可见度,而不会令对向行驶驾驶员感到眩目,显著优化了夜间驾驶体验。此外,EVIYOS® LED还具备
    艾迈斯欧司朗 2024-12-13 15:00 40浏览
  • 本文将介绍基于米尔电子MYD-LT527开发板(米尔基于全志T527开发板)的OpenCV手势识别方案测试。摘自优秀创作者-小火苗米尔基于全志T527开发板一、软件环境安装1.安装OpenCVsudo apt-get install libopencv-dev python3-opencv2.安装pipsudo apt-get install python3-pip二、OpenCV手势识别步骤​1.图像获取:从摄像头或其他图像源获取手部图像。使用OpenCV的VideoCapture类可以捕获视
    米尔电子嵌入式 2024-12-13 15:19 29浏览
  • 家用国产固态继电器(SSR)已成为各行各业的基石,性能可靠、设计紧凑、效率高。这些先进的开关设备取代了传统的机电继电器,具有静音运行、使用寿命更长、可靠性更高等诸多优点。家用SSR专为从工业自动化到家用电器等各种应用而设计,展示了本地制造商的独创性和竞争力。国产固态继电器特点和优势家用SSR采用半导体技术制造,与传统继电器相比,具有很强的耐磨性。主要特点包括:静音无振动运行:SSR使用半导体元件进行开关,消除了机械噪音。响应时间快:是工业控制系统中高速开关的理想选择。耐用性:没有移动部件,即使在
    克里雅半导体科技 2024-12-13 16:49 39浏览
  • 串口调试助手软件:XCOM 也是一款专为嵌入式开发和硬件调试设计的强大工具,如正点原子串口调试助手 XCOM V2.6。这款软件支持多种串口参数配置,满足不同开发需求,广泛应用于嵌入式系统开发、硬件调试以及电子爱好者的项目开发中。XCOM在嵌入式开发和硬件调试中的作用主要体现在以下几个方面: 1. 串口通信测试:XCOM作为一款强大的串口调试工具,允许用户通过计算机的串口进行数据的发送与接收,从而实现对串口通信的测试。这对于验证硬件设备的通信协议、确保数据传输的正确性至关重要。 2. 数据发
    丙丁先生 2024-12-15 11:56 54浏览
  • 微软在2024年5月,定义了AI PC的软硬件规格效能,在随之而来的多样技术应用功能中,尤以「AI降噪技术」最让大众充满应用想象。不同于传统的降噪技术,AI降噪技术理论上能够更准确地区分语音与背景噪音,甚至能识别出重要警报与噪声的差异,但应用技术的进步,相对也面临功能及效能验证的评估新挑战!面临的困难新型的AI降噪技术不仅能应用于麦克风的降噪,还能在视频会议中滤除来自对方的背景噪音,从而使本机扬声器能够播放出更加纯净的对方语音。这项技术的进步,使得厂商在评估降噪性能时,必须考虑多样化的噪声源和应
    百佳泰测试实验室 2024-12-13 10:00 42浏览
  • 一、引言在数字化时代,芯片作为现代科技的核心,其制造过程却常被视作神秘的黑箱。菊地正典的《大话芯片制造》为我们揭开了这层神秘的面纱,以通俗易懂的方式,全面系统地介绍了芯片制造的各个环节。作为一名电子信息技术专业的教育工作者,我深感这本书不仅为学生提供了宝贵的知识资源,也让我对芯片制造及其在现代社会中的作用有了更深刻的理解。二、生活中的芯片印记芯片的影响渗透到我们日常生活的每一个角落。从智能手机的闹钟唤醒,到交通卡的便捷支付,再到智能家居的智能化功能,芯片以其强大的运算和处理能力,为我们的现代生活
    月光 2024-12-16 11:52 18浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-13 23:20 48浏览
  • 提高团队响应速度,优化维护运营在工业或商业建筑中,集中告警管理已成为确保安全性或检测故障的必备工具。通过将所有安全系统集中管理,企业能够将所有告警统一在一个HMI界面中,大幅提升响应速度。关键要点✔ 集成所有安全系统,获取全面的告警视图。✔ 集中管理告警,可自动触发维护请求,提升团队响应效率。一、安全系统的统一管理通过集中管理,监控摄像头、对讲系统、入侵检测、火灾报警和门禁控制等安全设备可以整合到一个统一的界面中。这不仅提供了全局的告警视图,还能更好地检测潜在威胁。1.实时全局视图通过全面掌握设
    宏集科技 2024-12-13 15:58 32浏览
  • 光耦合器是现代电子系统中的关键组件,可在实现电路间信号传输的同时提供电气隔离。然而,人们经常对其功能、选择和应用感到困惑。本文旨在澄清常见的误解,并为工程师和业余爱好者提供必要的见解。什么是光耦合器?光耦合器或光隔离器由封装在一个封装中的发光二极管(LED)和光电探测器(如光电晶体管或光电二极管)组成。当电流通过LED时,LED会发光。光电探测器检测到该光,并产生相应的输出信号。这种机制允许在电气隔离输入和输出的同时传输信号,保护敏感元件免受高压和噪声的影响。关于光耦合器的常见困惑1.了解功能许
    腾恩科技-彭工 2024-12-13 16:17 41浏览
  • 光耦合器是一种重要的电子元件,其在电子信号隔离和传输中的作用不可替代。自20世纪60年代首次被研发以来,光耦合器经历了从基础隔离器件到高性能元件的不断演化,在现代电子设备中占据了重要地位。本文将深入探讨光耦合器的发展历程、技术特点以及在当今科技领域中的广泛应用。光耦合器的诞生背景光耦合器的诞生源于20世纪60年代,为了解决电子信号在不同电路之间传输时的隔离问题,科学家们设计了一种基于光信号传递的全新器件。光耦合器通过发光二极管(LED)将电信号转化为光信号,再由光敏器件接收并重新转换为电信号,从
    腾恩科技-彭工 2024-12-13 16:18 39浏览
  • 通过桌面双击播放音频​通过桌面播放音频没有声音时,可以查看sound(声音)选项是否设置为speakers(扬声器)播放。、命令行播放音频通过aplay -l查看声卡系统默认配置的声卡是rockchipes8388,通过aplay -l命令确定是第几个声卡,如下所示:root@Industio:/$ aplay -l**** List of PLAYBACK Hardware Devices ****card 0: rockchipdp0 [rockchip,dp0], device 0: ro
    Industio_触觉智能 2024-12-13 11:14 22浏览
  •        霍尔传感器是一种基于霍尔效应的传感器。霍尔效应指的是当通过一个导体的电流受到外部磁场的影响时,导体内部将会产生一种电场,使得在导体两端的电势差发生变化,这种电势差变化称为霍尔电势差。利用这种现象,可以设计出一种可以测量磁场强度和方向的传感器,即霍尔传感器。  霍尔传感器分为线型霍尔传感器和开关型霍尔传感器两种。  (一)开关型霍尔传感器由稳压器、霍尔元件、差分放大器,斯密特触发器和输出级组成,它输出数字量。开关型霍尔传感器还有一种特
    锦正茂科技 2024-12-14 10:58 53浏览
  • 概述 Cyclone 10 GX器件的ALM结构与Cyclone V类似,所以在Cyclone 10 GX器件上实现TDC功能理论上是可以完全参考甚至移植自Cyclone V系列的成功案例。但是,现实却是更多的问题出现当在Cyclone 10 GX使用和Cyclone V同样策略实现TDC的时候。 本文主要记录在Cyclone 10 GX器件上实现TDC时的探索,并为后续TDC设计、测试等展开前期研究。Cyclone 10 GX ALM结构 如图1所示,Cyclone 10 GX器件的ALM结构
    coyoo 2024-12-14 17:15 51浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-14 20:56 53浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦