当前位置: 首页 > news >正文

【嵌入式Linux应用开发基础】多线程编程

目录

一、基本概念

二、相关 API

2.1.  线程创建

2.2.  线程等待 

2.3.  线程退出 

2.4.  互斥锁

2.5.  条件变量 

2.6. 使用示例

三、线程的属性设置

四、多线程编程中的问题和同步

五、多线程编程的实践

六、参考资料


在嵌入式 Linux 应用开发中,多线程编程是一项非常重要的技术,它允许程序同时执行多个任务,提高系统的并发处理能力和响应速度。

一、基本概念

  • 线程:线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间、文件描述符等,但每个线程有自己独立的栈空间和程序计数器。

  • 多线程编程:多线程编程是指在一个程序中同时创建和管理多个线程,每个线程可以独立执行不同的任务。通过多线程编程,可以实现并发执行,提高程序的性能和效率。

  • 线程与进程的区别:线程共享进程资源(内存、文件描述符),创建和切换开销更小,适合资源受限的嵌入式系统。

  • POSIX线程库(pthread):Linux下多线程开发的标准API,需链接-lpthread

二、相关 API

在 Linux 系统中,使用 POSIX 线程库(pthread)来进行多线程编程。以下是一些常用的 API:

2.1.  线程创建

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
  • 参数说明
    • thread:指向pthread_t类型的指针,用于存储新创建线程的 ID。
    • attr:指向pthread_attr_t类型的指针,用于设置线程的属性,若为NULL,则使用默认属性。
    • start_routine:线程的入口函数,该函数的返回值和参数类型都为void *
    • arg:传递给线程入口函数的参数。
  • 返回值:成功返回 0,失败返回错误码。

2.2.  线程等待 

#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);
  • 参数说明
    • thread:要等待的线程的 ID。
    • retval:指向void *类型的指针,用于存储线程的返回值。
  • 返回值:成功返回 0,失败返回错误码。

2.3.  线程退出 

#include <pthread.h>

void pthread_exit(void *retval);
  • 参数说明retval:线程的返回值。

2.4.  互斥锁

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
  • 功能说明
    • pthread_mutex_init:初始化互斥锁。
    • pthread_mutex_lock:加锁,若互斥锁已被其他线程持有,则当前线程会阻塞。
    • pthread_mutex_unlock:解锁。
    • pthread_mutex_destroy:销毁互斥锁。

2.5.  条件变量 

#include <pthread.h>

int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_destroy(pthread_cond_t *cond);
  • 功能说明
    • pthread_cond_init:初始化条件变量。
    • pthread_cond_wait:等待条件变量,会自动释放互斥锁,被唤醒后会重新加锁。
    • pthread_cond_signal:唤醒一个等待该条件变量的线程。
    • pthread_cond_broadcast:唤醒所有等待该条件变量的线程。
    • pthread_cond_destroy:销毁条件变量。 

2.6. 使用示例

以下是一个简单的多线程编程示例,包含线程创建、线程等待和互斥锁的使用:

#include <stdio.h>
#include <pthread.h>

// 定义互斥锁
pthread_mutex_t mutex;
// 共享资源
int shared_variable = 0;

// 线程函数
void* thread_function(void* arg) {
    int i;
    for (i = 0; i < 100000; i++) {
        // 加锁
        pthread_mutex_lock(&mutex);
        shared_variable++;
        // 解锁
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
    pthread_t thread1, thread2;

    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);

    // 创建线程
    pthread_create(&thread1, NULL, thread_function, NULL);
    pthread_create(&thread2, NULL, thread_function, NULL);

    // 等待线程结束
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    // 输出共享资源的值
    printf("Shared variable value: %d\n", shared_variable);

    return 0;
}

编译和运行:使用以下命令编译上述代码

gcc -o multi_thread_example multi_thread_example.c -lpthread

运行编译后的可执行文件:

./multi_thread_example

三、线程的属性设置

线程的属性可以通过pthread_attr_t结构体进行设置。以下是一些常见的线程属性:

  • 线程分离状态:可以通过pthread_attr_setdetachstate函数设置线程为分离状态,这样线程在终止时会自动释放资源,而不需要其他线程调用pthread_join来等待。
  • 线程栈大小:可以通过pthread_attr_setstacksize函数设置线程的栈大小。
  • 线程调度策略:可以通过pthread_attr_setschedpolicy等函数设置线程的调度策略和优先级。
  • 设置线程属性:如分离状态、栈大小、调度策略。
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  • 优先级与调度策略:实时系统常用SCHED_FIFOSCHED_RR
struct sched_param param;
param.sched_priority = 10;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);

四、多线程编程中的问题和同步

  • 竞态条件:当多个线程同时访问共享资源,并且至少有一个线程在修改该资源时,就可能发生竞态条件。竞态条件会导致程序的行为变得不确定。
  • 死锁:当两个或多个线程相互等待对方释放资源,从而无法继续执行时,就发生了死锁。死锁是一种严重的并发问题,通常会导致程序崩溃。

为了解决这些问题,需要使用同步机制来协调线程之间的执行。常见的同步机制包括:

  • 互斥锁:互斥锁用于保护临界资源,确保同一时间只有一个线程可以访问该资源。当线程需要访问临界资源时,会先尝试获取互斥锁;如果锁已被其他线程持有,则线程会阻塞等待直到锁被释放。
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock);
// 临界区操作
pthread_mutex_unlock(&lock);
  • 条件变量:条件变量用于线程间的同步,它允许线程在某些条件不满足时等待,并在条件满足时被唤醒。条件变量通常与互斥锁一起使用,以确保对共享资源的访问是安全的。
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
// 等待条件
pthread_cond_wait(&cond, &mutex);
// 通知条件满足
pthread_cond_signal(&cond);
  • 信号量:信号量是一种更通用的同步机制,它可以用于控制对共享资源的访问数量。信号量的值表示可用资源的数量;当线程需要访问资源时,会先尝试对信号量进行P操作(减1);如果信号量的值大于0,则操作成功,线程可以继续执行;否则,线程会阻塞等待直到信号量的值大于0。当线程释放资源时,会对信号量进行V操作(加1),以唤醒等待的线程。

五、多线程编程的实践

在嵌入式Linux应用开发中,多线程编程的实践通常包括以下几个步骤:

  • 设计线程结构:根据应用程序的需求,设计合理的线程结构,包括线程的数量、职责和交互方式等。
  • 编写线程函数:为每个线程编写相应的执行函数,实现线程的具体功能。
  • 创建和管理线程:使用pthread库函数创建和管理线程,包括设置线程属性、启动线程和等待线程终止等。
  • 实现线程同步:使用互斥锁、条件变量和信号量等同步机制来协调线程之间的执行,确保程序的正确性和稳定性。
  • 测试和调试:对多线程程序进行充分的测试和调试,以发现和解决潜在的并发问题。

综上所述,多线程编程在嵌入式Linux应用开发中具有重要意义。通过合理设计和使用线程,可以充分利用CPU资源,提高程序的运行效率和响应速度。同时,也需要注意线程同步和互斥问题,以确保程序的正确性和稳定性。

六、参考资料

  • 《Unix 环境高级编程》:对 UNIX 环境下的进程、线程、文件操作、网络编程等进行了深入讲解,关于多线程编程部分详细介绍了线程的创建、同步、互斥等机制,是嵌入式 Linux 应用开发中多线程编程的经典参考书籍。
  • 《嵌入式 Linux 系统编程》:涉及嵌入式 Linux 系统设备驱动开发的各个环节,也包含 Linux 多线程相关内容,如线程的同步与互斥等知识,通过详细的示例,由浅入深地指导初学者掌握相关知识。
  • 《C Primer Plus》:虽然不是专门针对多线程编程,但十 C 语言的经典入门书籍。
  • POSIX 线程库文档:Linux 下多线程编程主要通过 POSIX 线程库来实现,官方的 POSIX 线程库文档是非常权威的参考资料,详细介绍了线程相关函数的使用方法、参数含义以及返回值等。
  • 开源项目代码:许多开源的嵌入式 Linux 项目中都有多线程编程的实际应用,如一些基于 Linux 的实时操作系统(RTOS)项目,通过阅读这些开源项目的代码,可以学习到实际应用中多线程编程的技巧和最佳实践。

相关文章:

  • 基于AIGC的图表自动化生成工具「图表狐」深度评测:如何用自然语言30秒搞定专业级数据可视化?
  • ABC381E题解
  • 数据结构之二叉树的定义及实现
  • Unity使用IL2CPP打包时,我们应该注意什么?如何避免(可以举例说明)
  • 创建虚拟环境以及配置对应的项目依赖
  • DeepSeek技术全景解析:架构创新与行业差异化竞争力
  • Spring Boot数据访问(JDBC)全解析:从基础配置到高级调优
  • 20-R 绘图 - 饼图
  • 游戏设计模式阅读 - 游戏循环
  • Spring Security+JWT (5)
  • 红队内网攻防渗透:内网渗透之内网对抗:实战项目VPC2打靶父子域三层路由某绒免杀下载突破约束委派域控提权
  • 深度解析:大模型在多显卡服务器下的通信机制与分布式训练——以DeepSeek、Ollama和vLLM为例
  • 安全面试4
  • 谷歌浏览器更新后导致的刷新数据无法显示
  • C++标准库提供了哪些智能指针类型以及它们的区别
  • 小红书运营教程(内容笔记01)
  • 网络安全 | 信息安全管理体系(ISMS)
  • Linux文件系统----磁盘级文件
  • 《GNU/Linux Shell命令全解析》
  • CSS背景属性
  • 公司做网站推广需要多少钱/企业宣传文案
  • 湛江电子商务网站建设/手机百度云电脑版入口
  • 广西壮族自治区住房和建设厅网站/西安做网站的公司
  • 北京市住房和城乡建设委官方网站/免费的html网站
  • 太原医疗网站建设/软文的概念是什么
  • 新城疫怎么治疗/商丘seo公司