Linux下线程间同步实现方式详解

server/2025/2/7 1:12:38/

目录

概述

1. 互斥锁(Mutex)

2. 条件变量(Condition Variable)

3. 信号量(Semaphore)

4. 读写锁(Read-Write Lock)

5. 屏障(Barrier)

6. 自旋锁(Spinlock)

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

总结


概述

Linux 中线程(Thread)是共享进程内存空间的轻量级执行单元,线程间通信(IPC)主要通过 共享内存 和 同步机制 实现。在Linux操作系统中,线程间实现同步通信的方式主要包括互斥锁(Mutex)、条件变量(Condition Variable)、信号量(Semaphore)、读写锁(Read-Write Lock)等。以下是常用方式及其原理、场景和代码示例。

1. 互斥锁(Mutex)

原理

  • 通过锁机制保护共享资源,同一时间仅允许一个线程访问临界区。

  • 线程在进入临界区前加锁,退出时解锁。

适用场景

  • 保护共享变量、数据结构等临界资源。

  • 防止数据竞争(Data Race)。

C 语言示例

#include <stdio.h>
#include <pthread.h>pthread_mutex_t mutex;
int counter = 0;void* thread_func(void* arg) {pthread_mutex_lock(&mutex); // 加锁counter++;printf("Counter: %d\n", counter);pthread_mutex_unlock(&mutex); // 解锁return NULL;
}int main() {pthread_t t1, t2;pthread_mutex_init(&mutex, NULL);pthread_create(&t1, NULL, thread_func, NULL);pthread_create(&t2, NULL, thread_func, NULL);pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_mutex_destroy(&mutex);return 0;
}

2. 条件变量(Condition Variable)

原理

  • 允许线程在条件不满足时阻塞,等待其他线程发送信号唤醒。

  • 必须与互斥锁配合使用,避免竞争条件。

适用场景

  • 生产者-消费者模型。

  • 线程间状态同步(如任务队列空/满)。

C 语言示例

#include <stdio.h>
#include <pthread.h>pthread_mutex_t mutex;
pthread_cond_t cond;
int data_ready = 0;void* producer(void* arg) {pthread_mutex_lock(&mutex);data_ready = 1;printf("Producer: 数据已生成\n");pthread_cond_signal(&cond); // 发送信号pthread_mutex_unlock(&mutex);return NULL;
}void* consumer(void* arg) {pthread_mutex_lock(&mutex);while (!data_ready) {pthread_cond_wait(&cond, &mutex); // 等待信号}printf("Consumer: 收到数据\n");pthread_mutex_unlock(&mutex);return NULL;
}int main() {pthread_t prod, cons;pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond, NULL);pthread_create(&prod, NULL, producer, NULL);pthread_create(&cons, NULL, consumer, NULL);pthread_join(prod, NULL);pthread_join(cons, NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);return 0;
}

3. 信号量(Semaphore)

原理

  • 通过计数器控制资源访问,支持 P(等待,计数器减)和 V(释放,计数器加)操作。

  • 可以解决多线程同步问题,支持多个线程同时访问有限资源。

适用场景

  • 控制资源池(如数据库连接池)。

  • 限制并发线程数量。

C 语言示例

#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>sem_t sem;
int shared_data = 0;void* thread_func(void* arg) {sem_wait(&sem); // P 操作shared_data++;printf("Thread %ld: shared_data = %d\n", (long)arg, shared_data);sem_post(&sem); // V 操作return NULL;
}int main() {sem_init(&sem, 0, 1); // 初始值为1(二进制信号量)pthread_t t1, t2;pthread_create(&t1, NULL, thread_func, (void*)1);pthread_create(&t2, NULL, thread_func, (void*)2);pthread_join(t1, NULL);pthread_join(t2, NULL);sem_destroy(&sem);return 0;
}

4. 读写锁(Read-Write Lock)

原理

  • 允许多个读线程同时访问共享资源,但写线程独占访问。

  • 读优先或写优先策略可选。

适用场景

  • 读多写少的场景(如配置管理、缓存系统)。

C 语言示例

#include <stdio.h>
#include <pthread.h>pthread_rwlock_t rwlock;
int data = 0;void* reader(void* arg) {pthread_rwlock_rdlock(&rwlock); // 读锁printf("Reader: data = %d\n", data);pthread_rwlock_unlock(&rwlock);return NULL;
}void* writer(void* arg) {pthread_rwlock_wrlock(&rwlock); // 写锁data++;printf("Writer: 更新 data 为 %d\n", data);pthread_rwlock_unlock(&rwlock);return NULL;
}int main() {pthread_rwlock_init(&rwlock, NULL);pthread_t r1, r2, w;pthread_create(&r1, NULL, reader, NULL);pthread_create(&w, NULL, writer, NULL);pthread_create(&r2, NULL, reader, NULL);pthread_join(r1, NULL);pthread_join(w, NULL);pthread_join(r2, NULL);pthread_rwlock_destroy(&rwlock);return 0;
}

5. 屏障(Barrier)

原理

  • 使多个线程在某个点同步,所有线程到达屏障后继续执行。

适用场景

  • 并行计算中分阶段处理(如 MapReduce)。

C 语言示例

#include <stdio.h>
#include <pthread.h>pthread_barrier_t barrier;void* task(void* arg) {printf("线程 %ld 执行第一阶段\n", (long)arg);pthread_barrier_wait(&barrier); // 等待所有线程到达printf("线程 %ld 执行第二阶段\n", (long)arg);return NULL;
}int main() {pthread_barrier_init(&barrier, NULL, 3); // 等待3个线程pthread_t t1, t2, t3;pthread_create(&t1, NULL, task, (void*)1);pthread_create(&t2, NULL, task, (void*)2);pthread_create(&t3, NULL, task, (void*)3);pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_join(t3, NULL);pthread_barrier_destroy(&barrier);return 0;
}

6. 自旋锁(Spinlock)

原理

  • 线程在等待锁时不会休眠,而是循环检查锁状态(忙等待)。

  • 适用于锁持有时间短的场景。

适用场景

  • 内核编程或实时系统。

  • 避免线程切换开销。

C 语言示例

#include <stdio.h>
#include <pthread.h>pthread_spinlock_t spinlock;
int counter = 0;void* thread_func(void* arg) {pthread_spin_lock(&spinlock);counter++;printf("Counter: %d\n", counter);pthread_spin_unlock(&spinlock);return NULL;
}int main() {pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE);pthread_t t1, t2;pthread_create(&t1, NULL, thread_func, NULL);pthread_create(&t2, NULL, thread_func, NULL);pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_spin_destroy(&spinlock);return 0;
}

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

原理

  • 每个线程拥有变量的独立副本,互不干扰。

  • 使用 __thread 关键字或 pthread_key_create 实现。

适用场景

  • 需要线程私有数据(如错误码、日志上下文)。

C 语言示例

#include <stdio.h>
#include <pthread.h>__thread int tls_var = 0; // GCC 扩展语法void* thread_func(void* arg) {tls_var = (int)(long)arg;printf("线程 %ld: tls_var = %d\n", (long)arg, tls_var);return NULL;
}int main() {pthread_t t1, t2;pthread_create(&t1, NULL, thread_func, (void*)1);pthread_create(&t2, NULL, thread_func, (void*)2);pthread_join(t1, NULL);pthread_join(t2, NULL);return 0;
}

总结

对比如下

根据具体场景选择合适的同步机制,例如:

  • 高并发读 → 读写锁。

  • 短临界区 → 自旋锁。

  • 多阶段任务 → 屏障。

 


http://www.ppmy.cn/server/165551.html

相关文章

tkvue 入门,像写html一样写tkinter

介绍 没有官网&#xff0c;只有例子 安装 像写vue 一样写tkinter 代码 pip install tkvue作者博客 修改样式 import tkvue import tkinter.ttk as ttktkvue.configure_tk(theme"clam")class RootDialog(tkvue.Component):template """ <Top…

DBeaver连接MySQL提示Access denied for user ‘‘@‘ip‘ (using password: YES)的解决方法

在使用DBeaver连接MySQL数据库时&#xff0c;如果遇到“Access denied for user ip (using password: YES)”的错误提示&#xff0c;说明用户认证失败。此问题通常与数据库用户权限、配置错误或网络设置有关。本文将详细介绍解决此问题的步骤。 一、检查用户名和密码 首先&am…

(2025,LLM,下一 token 预测,扩散微调,L2D,推理增强,可扩展计算)从大语言模型到扩散微调

Large Language Models to Diffusion Finetuning 目录 1. 概述 2. 研究背景 3. 方法 3.1 用于 LM 微调的高斯扩散 3.2 架构 4. 主要实验结果 5. 结论 1. 概述 本文提出了一种新的微调方法——LM to Diffusion (L2D)&#xff0c;旨在赋予预训练的大语言模型&#xff08;…

手撕Diffusion系列 - 第十一期 - lora微调 - 基于Stable Diffusion(代码)

手撕Diffusion系列 - 第十一期 - lora微调 - 基于Stable Diffusion&#xff08;代码&#xff09; 目录 手撕Diffusion系列 - 第十一期 - lora微调 - 基于Stable Diffusion&#xff08;代码&#xff09;Stable Diffusion 原理图Stable Diffusion的原理解释Stable Diffusion 和Di…

stm32小白成长为高手的学习步骤和方法

我们假定大家已经对STM32的书籍或者文档有一定的理解。如不理解&#xff0c;请立即阅读STM32的文档&#xff0c;以获取最基本的知识点。STM32单片机自学教程 这篇博文也是一篇不错的入门教程&#xff0c;初学者可以看看&#xff0c;讲的真心不错。 英文好的同学&#xf…

【计算机视觉】目标跟踪应用

一、简介 目标跟踪是指根据目标物体在视频当前帧图像中的位置&#xff0c;估计其在下一帧图像中的位置。视频帧由t到t1的检测&#xff0c;虽然也可以使用目标检测获取&#xff0c;但实际应用中往往是不可行的&#xff0c;原因如下&#xff1a; 目标跟踪的目的是根据目标在当前…

DEEPSEKK GPT等AI体的出现如何重构工厂数字化架构:从设备控制到ERP MES系统的全面优化

随着深度学习&#xff08;DeepSeek&#xff09;、GPT等先进AI技术的出现&#xff0c;工厂的数字化架构正在经历前所未有的变革。AI的强大处理能力、预测能力和自动化决策支持&#xff0c;将大幅度提升生产效率、设备管理、资源调度以及产品质量管理。本文将探讨AI体&#xff08…

人工智能赋能企业系统架构设计:以ERP与CRM系统为例

一、引言 1.1 研究背景与意义 在数字化时代&#xff0c;信息技术飞速发展&#xff0c;人工智能&#xff08;Artificial Intelligence, AI&#xff09;作为一项具有变革性的技术&#xff0c;正深刻地影响着各个领域。近年来&#xff0c;AI 在技术上取得了显著突破&#xff0c;…