Linux实现线程同步的多种方式汇总

 更新时间:2025年06月09日 11:34:03   作者:kaede  
本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例代码展示了如何在多线程环境中正确地管理共享资源,确保线程安全,需要的朋友可以参考下

什么是线程同步?

想象一下超市收银台:如果所有顾客(线程)同时挤向同一个收银台(共享资源),场面会一片混乱。线程同步就是给顾客们发"排队号码牌",确保:

  • 有序访问:每次只处理一个顾客
  • 协调工作:收银员(CPU)高效服务
  • 避免冲突:防止算错账(数据错误)

Linux提供5种"排队机制"解决多线程协作问题:

一、互斥锁(单人洗手间规则)

#include <pthread.h>

// 创建锁(相当于洗手间的"有人/无人"标识)
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void* thread_task(void* arg) {
        // 尝试进入(如果里面有人就排队等待)
        pthread_mutex_lock(&lock);

        /* 临界区开始(你的"私人时间") */
        printf("Thread %d using resource\n", *(int*)arg);
        sleep(1); // 模拟耗时操作
        /* 临界区结束 */

        // 开门出来(让下一位使用)
        pthread_mutex_unlock(&lock);
        return NULL;
}

适用场景:

  • 文件写入操作
  • 银行账户余额修改
  • 任何需要"独享"资源的场景

特点:

  • 简单易用
  • 过度使用会降低并发性能

二、条件变量(咖啡厅取餐系统)

pthread_cond_t order_ready = PTHREAD_COND_INITIALIZER;
pthread_mutex_t counter_lock = PTHREAD_MUTEX_INITIALIZER;
int order_number = 0;

// 顾客线程(等待取餐)
void* customer(void* arg) {
        pthread_mutex_lock(&counter_lock);
        while(order_number == 0) { // 必须用while循环检查
                pthread_cond_wait(&order_ready, &counter_lock); // 放下锁等待通知
        }
        printf("Got order %d!\n", order_number);
        pthread_mutex_unlock(&counter_lock);
        return NULL;
}

// 厨师线程(通知取餐)
void* chef(void* arg) {
        sleep(2); // 模拟做饭时间
        pthread_mutex_lock(&counter_lock);
        order_number = 123;
        pthread_cond_signal(&order_ready); // 叫号通知顾客
        pthread_mutex_unlock(&counter_lock);
        return NULL;
}

工作流程:

  • 顾客:锁定柜台 → 检查订单 → 等待叫号
  • 厨师:完成订单 → 锁定柜台 → 更新订单 → 发送通知
  • 顾客:被唤醒 → 重新检查 → 取餐

适用场景:

  • 生产者-消费者模型(如消息队列)
  • 线程间任务协调

三、自旋锁(抢车位)

pthread_spinlock_t parking_lock;

// 初始化锁(停车场入口)
pthread_spin_init(&parking_lock, PTHREAD_PROCESS_PRIVATE); 

void* driver(void* arg) {
        // 开车绕圈找空位(CPU忙等待)
        pthread_spin_lock(&parking_lock);

        /* 停车成功(临界区) */
        printf("Car %d parked\n", *(int*)arg);

        // 开走释放车位
        pthread_spin_unlock(&parking_lock);
        return NULL;
}

适用场景:

  • 极短操作(<0.1毫秒)
  • 内核开发
  • 实时系统

注意事项:

  • 会浪费CPU资源
  • 比互斥锁响应更快

锁类型对比表:

场景推荐锁类型类比
短时间独占操作自旋锁快速便利店购物
长时间独占操作互斥锁餐厅包间用餐
多读少写读写锁图书馆
线程组协调屏障旅行团集合
事件通知条件变量咖啡厅叫号系统

到此这篇关于Linux实现线程同步的五种方式的文章就介绍到这了,更多相关Linux线程同步内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Linux VIM编辑二进制文件方式

    Linux VIM编辑二进制文件方式

    这篇文章主要介绍了Linux VIM编辑二进制文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 基于windowx的Hyper-v安装CentOS系统

    基于windowx的Hyper-v安装CentOS系统

    这篇文章主要介绍了基于windowx的Hyper-v安装CentOS系统 ,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • Linux中避免客户端与服务端的端口冲突

    Linux中避免客户端与服务端的端口冲突

    在Linux系统中,为了防止客户端程序在分配TCP源端口时使用到服务器程序绑定的特定端口(例如12345),可以采用多种策略来避免端口冲突,总体而言,优先使用sysctl设置保留端口是最简单有效的解决方案,但也可以采用其他方法来确保端口不会发生冲突
    2024-10-10
  • linux服务器上openssl版本升级方式

    linux服务器上openssl版本升级方式

    文章详细介绍了在Linux服务器上升级OpenSSL版本的步骤,包括查看当前版本、检查yum源、下载源码、编译安装、创建软链、更新动态链接库以及验证版本
    2025-03-03
  • 一文详解Linux如何查询服务和定位可执行文件

    一文详解Linux如何查询服务和定位可执行文件

    这篇文章主要为大家详细介绍了Linux中查询服务和定位可执行文件的相关命令,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-11-11
  • 利用lynis如何进行linux漏洞扫描详解

    利用lynis如何进行linux漏洞扫描详解

    这篇文章主要给大家介绍了关于利用lynis如何进行linux漏洞扫描的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-06-06
  • Linux挂载本地操作系统ISO镜像的操作步骤

    Linux挂载本地操作系统ISO镜像的操作步骤

    这篇文章主要介绍了在服务器上挂载ISO文件的两种方法:使用loop设备和直接挂载光驱设备,选择哪种方法取决于你手里的是ISO文件路径还是光驱设备节点,通过简单的判断命令可以快速选择合适的挂载方式,需要的朋友可以参考下
    2026-03-03
  • Linux系统之iostat命令的基本使用详解

    Linux系统之iostat命令的基本使用详解

    iostat命令是Linux/Unix系统中用于监控磁盘I/O活动的工具,可以显示磁盘的读写速率、I/O等待时间、CPU使用率等信息,通过分析这些指标,可以帮助系统管理员发现性能瓶颈,并进行优化
    2025-12-12
  • 如何利用Gitlab-ci持续部署到远程机器(详细教程)

    如何利用Gitlab-ci持续部署到远程机器(详细教程)

    这篇文章主要介绍了如何利用Gitlab-ci持续部署到远程机器(详细教程),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Centos7 Mysql 5.6 多主一从 解决方案与详细配置

    Centos7 Mysql 5.6 多主一从 解决方案与详细配置

    这篇文章主要介绍了Centos7 Mysql 5.6 多主一从 解决方案与详细配置,需要的朋友可以参考下
    2016-04-04

最新评论