4、多线程编程中的互斥算法详解

多线程编程中的互斥算法详解

在多处理器编程中,互斥是一种非常普遍的协调形式。本文将深入探讨经典的互斥算法,这些算法通过读写共享内存来实现,虽然在实际中较少使用,但它们能帮助我们理解同步领域中出现的算法和正确性问题。

1. 时间的概念

在并发计算中,对时间的推理至关重要。我们有时希望事件同时发生,有时则希望它们在不同时间发生。为了清晰地描述事件和时间间隔,我们引入了一些简单的词汇和符号。

事件是瞬间发生的,不同的事件发生在不同的时间。线程 A 会产生一系列事件,我们用 $a_j^i$ 表示事件 $a_i$ 的第 $j$ 次发生。如果事件 $a$ 发生的时间早于事件 $b$,则记为 $a → b$,这种先后关系是事件的全序关系。

时间间隔 $(a_0, a_1)$ 是事件 $a_0$ 和 $a_1$ 之间的持续时间。如果间隔 $I_A = (a_0, a_1)$ 的最后一个事件早于间隔 $I_B = (b_0, b_1)$ 的第一个事件,即 $a_1 → b_0$,则记为 $I_A → I_B$,这种关系是间隔的偏序关系。没有这种先后关系的间隔称为并发间隔。

2. 临界区

在单线程系统中, Counter 类的实现是正确的,但在多线程环境中会出现问题。问题出在多个线程同时读取和更新 value 字段时。为了避免这个问题,我们可以将这两行代码转换为临界区,即一次只能由一个线程执行的代码块,这种属性称为互斥。

实现互斥的标准方法是使用 Lock 对象,其接口如下:

public interface Lock {
    public void lock(); // 进入临界区之前
    public void unlock(); // 离开临界区之前
}

使用 Lock 对象的 Counter 类示例:

public class Counter {
    private long value;
    private Lock lock; // 保护临界区
    public long getAndIncrement() {
        lock.lock(); // 进入临界区
        try {
            long temp = value; // 在临界区
            value = temp + 1; // 在临界区
            return temp;
        } finally {
            lock.unlock(); // 离开临界区
        }
    }
}

线程使用 lock() 和 unlock() 方法时必须遵循特定格式:
1. 每个临界区与一个唯一的 Lock 对象关联。
2. 线程进入临界区时调用该对象的 lock() 方法。
3. 线程离开临界区时调用 unlock() 方法。

一个好的 Lock 算法应满足以下属性:
- 互斥性 :不同线程的临界区不会重叠。对于线程 A 和 B,以及整数 j 和 k,要么 $CS_k^A → CS_j^B$,要么 $CS_j^B → CS_k^A$。
- 无死锁 :如果某个线程尝试获取锁,那么一定有线程能够成功获取锁。
- 无饥饿 :每个尝试获取锁的线程最终都会成功,每个 lock() 调用最终都会返回。

需要注意的是,无饥饿属性意味着无死锁,但无死锁并不一定意味着无饥饿。互斥性是确保计算结果正确的关键,无死锁属性确保系统不会“冻结”,而无饥饿属性虽然理想,但在实际中有些算法可能无法满足。

3. 双线程解决方案
3.1 LockOne 类

LockOne 算法的代码如下:

class LockOne implements Lock {
    private boolean[] flag = new boolean[2];
    public void lock() {
        int i = ThreadID.get();
        int j = 1 - i;
        flag[i] = true;
        while (flag[j]) {} // 等待
    }
    public void unlock() {
        int i = ThreadID.get();
        flag[i] = false;
    }
}

该算法满足互斥性,但存在死锁问题。如果两个线程的 writeA(flag[A] = true) 和 writeB(flag[B] = true) 事件在 readA(flag[B]) 和 readB(flag[A]) 事件之前发生,那么两个线程将永远等待。不过,如果一个线程先于另一个线程运行,则不会发生死锁。

3.2 LockTwo 类

LockTwo 算法的代码如下:

class LockTwo implements Lock {
    private int victim;
    public void lock() {
        int i = ThreadID.get();
        victim = i; // 让另一个线程先执行
        while (victim == i) {} // 等待
    }
    public void unlock() {}
}

该算法也满足互斥性,但如果一个线程完全领先于另一个线程运行,会发生死锁。然而,如果两个线程并发运行, lock() 方法可以成功。 LockOne 和 LockTwo 类相互补充,各自在对方会发生死锁的条件下能够正常工作。

3.3 Peterson 锁

Peterson 锁结合了 LockOne 和 LockTwo 算法,是一种无饥饿的锁算法,代码如下:

class Peterson implements Lock {
    private boolean[] flag = new boolean[2];
    private int victim;
    public void lock() {
        int i = ThreadID.get();
        int j = 1 - i;
        flag[i] = true; // 表示自己感兴趣
        victim = i; // 让对方先执行
        while (flag[j] && victim == i) {}; // 等待
    }
    public void unlock() {
        int i = ThreadID.get();
        flag[i] = false; // 表示自己不再感兴趣
    }
}

该算法满足互斥性和无饥饿性,因此也满足无死锁性。

4. Filter 锁

Filter 锁是 Peterson 锁向多线程的直接扩展,适用于 n 个线程(n > 2)。该锁创建了 n - 1 个“等待室”,称为级别,线程在获取锁之前必须遍历这些级别。

Filter 锁的代码如下:

class Filter implements Lock {
    int[] level;
    int[] victim;
    public Filter(int n) {
        level = new int[n];
        victim = new int[n]; // 使用 1..n - 1
        for (int i = 0; i < n; i++) {
            level[i] = 0;
        }
    }
    public void lock() {
        int me = ThreadID.get();
        for (int i = 1; i < n; i++) { // 尝试进入级别 i
            level[me] = i;
            victim[i] = me;
            // 当存在冲突时自旋
            while ((∃k != me) (level[k] >= i && victim[i] == me)) {};
        }
    }
    public void unlock() {
        int me = ThreadID.get();
        level[me] = 0;
    }
}

级别满足两个重要属性:
- 至少有一个尝试进入级别 $\ell$ 的线程会成功。
- 如果有多个线程尝试进入级别 $\ell$,那么至少有一个线程会被阻塞。

可以证明,对于 0 到 n - 1 之间的 j,级别 j 最多有 n - j 个线程。进入临界区相当于进入级别 n - 1,因此 Filter 锁算法满足互斥性和无饥饿性。

下面是 Filter 锁线程通过各级别的流程图:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px

    A([非临界区]):::startend --> B(级别 0):::process
    B --> C(级别 1):::process
    C --> D(级别 2):::process
    D --> ...(...):::process
    ... --> E(级别 n-2):::process
    E --> F(级别 n-1):::process
    F --> G([临界区]):::startend

综上所述,这些互斥算法为我们理解多线程编程中的同步问题提供了重要的基础。不同的算法在不同的场景下有不同的表现,我们需要根据具体需求选择合适的算法。

多线程编程中的互斥算法详解

5. 不同互斥算法的对比分析

为了更清晰地了解各个互斥算法的特点,我们将对上述介绍的几种算法进行对比分析,以下是它们的对比表格:
| 算法名称 | 适用线程数 | 互斥性 | 无死锁性 | 无饥饿性 | 优缺点 |
| — | — | — | — | — | — |
| LockOne | 2 线程 | 满足 | 不满足(线程执行交错时会死锁) | 不满足 | 优点:如果一个线程先于另一个线程运行,不会死锁;缺点:线程执行交错易死锁 |
| LockTwo | 2 线程 | 满足 | 不满足(一个线程完全领先另一个线程时会死锁) | 不满足 | 优点:线程并发运行时 lock() 方法可成功;缺点:一个线程完全领先另一个线程会死锁 |
| Peterson |2 线程 | 满足 | 满足 | 满足 | 优点:简洁优雅,满足互斥、无死锁和无饥饿;缺点:仅适用于 2 线程 |
| Filter | n 线程(n > 2) | 满足 | 满足 | 满足 | 优点:是 Peterson 锁向多线程的扩展,适用于多线程;缺点:实现相对复杂 |

从表格中可以看出,不同的算法在适用场景和性能特点上存在差异。对于 2 线程的场景,如果线程执行顺序较为规律,LockOne 或 LockTwo 可能可以使用,但如果需要保证在各种情况下都正常工作,Peterson 锁是更好的选择。而对于多线程场景,Filter 锁则能满足需求。

6. 互斥算法的实际应用思考

在实际的多线程编程中,我们需要根据具体的业务场景来选择合适的互斥算法。以下是一些常见的应用场景及对应的算法选择建议:
1. 简单 2 线程场景且线程执行顺序可预测 :如果两个线程的执行顺序比较固定,例如一个线程总是先于另一个线程执行,那么可以考虑使用 LockOne 或 LockTwo 算法,因为它们的实现相对简单。
2. 2 线程场景且需要高可靠性 :在对系统稳定性要求较高,不允许出现死锁和饥饿情况的 2 线程场景中,Peterson 锁是首选,它能保证在各种情况下都能正常工作。
3. 多线程场景 :当涉及到多个线程时,Filter 锁可以提供互斥和无饥饿的保证,适用于大多数多线程同步的场景。

在使用这些算法时,还需要注意以下几点:
- 内存可见性 :在 Java 中,像 LockOne 中的 flag 数组,以及后续算法中的 victim 和 label 变量等,都需要声明为 volatile 以保证内存可见性。虽然在前面的代码示例中没有详细声明,但在实际使用中这是非常重要的。
- 异常处理 :在使用 lock() 和 unlock() 方法时,建议采用 try-finally 结构,确保在发生异常时锁也能被正确释放,避免死锁的发生。示例代码如下:

mutex.lock();
try {
    // 临界区代码
} finally {
    mutex.unlock();
}
7. 互斥算法的进一步优化思路

虽然上述算法已经能够解决多线程编程中的互斥问题,但在某些情况下,我们可能还需要对算法进行优化以提高性能。以下是一些可能的优化思路:
1. 减少自旋等待 :在一些算法中,如 LockOne 和 Filter 锁,存在自旋等待的情况,这会消耗 CPU 资源。可以考虑引入一些机制,如线程休眠或让步,减少自旋等待的时间。
2. 锁粒度优化 :在设计锁的使用时,应尽量减小锁的粒度,只对必要的代码块加锁,避免不必要的线程阻塞,提高并发性能。
3. 使用更高级的同步原语 :在 Java 中,除了手动实现的互斥算法,还可以使用一些高级的同步原语,如 ReentrantLock 、 Semaphore 等,它们在性能和功能上可能更强大。

8. 总结与展望

通过对多线程编程中互斥算法的深入研究,我们了解了不同算法的原理、特点和适用场景。从简单的 2 线程算法到多线程的扩展算法,每一种算法都有其独特的优势和局限性。在实际应用中,我们需要根据具体的业务需求和系统环境选择合适的算法,并注意内存可见性、异常处理等问题。

未来,随着计算机硬件的不断发展和多线程编程需求的增加,互斥算法也将不断演进。可能会出现更高效、更灵活的同步机制,以满足日益复杂的多线程应用场景。同时,对于互斥算法的研究也将更加深入,包括如何在分布式系统中实现高效的互斥等问题。

以下是一个简单的决策流程图,帮助我们在实际应用中选择合适的互斥算法:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px

    A([开始]):::startend --> B{线程数量}:::decision
    B -->|2 线程| C{线程执行顺序是否可预测}:::decision
    C -->|是| D(LockOne 或 LockTwo):::process
    C -->|否| E(Peterson):::process
    B -->|n 线程(n > 2)| F(Filter):::process
    D --> G([结束]):::startend
    E --> G
    F --> G

总之,多线程编程中的互斥算法是一个复杂而重要的领域,我们需要不断学习和实践,才能更好地应对各种多线程同步问题。

多线程编程—线程的同步与互斥 A . 线程一、线程的同步与互斥同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。 1、线程(进程)同步的主要任务答:在引入多线 阅读详情

相关推荐

Linux多线程之线程互斥

(。・∀・)ノ゙嗨!你好这里是ky233的主页:这里是ky233的主页,欢迎光临~type=blog点个关注不迷路⌯'▾'⌯。

ky233的博客 1500

【Linux C | 多线程编程】线程同步 | 互斥量(互斥锁)介绍和使用

本文介绍了Linux系统下,多线程编程常用的互斥量,先是介绍了需要互斥量的原因,然后介绍互斥量的使用,并给出使用例子。

wkd_007的博客 2294

4、多线程互斥算法详解

本文详细介绍了多线程环境下的经典互斥算法,包括双线程场景的LockOne、LockTwo和Peterson锁,以及多线程场景的Filter锁和Bakery锁。通过分析这些算法的互斥性、无死锁性和无饥饿性,探讨了它们在不同应用场景下的优劣。此外,文章还对各算法的性能进行了比较,并结合实际应用说明了互斥算法在并发编程中的重要性。

pandas7gardener的博客 48

linux多线程编程——同步与互斥

我们在前面文章中已经分析了多线程VS多进程,也分析了线程的使用,现在我们来讲解一下linux多线程编程之同步与互斥。 现在,我们不管究竟是多线程好还是多进程好,先讲解一下,为什么要使用多线程? 一、 为什么要用多线程技术? 1、避免阻塞,大家知道,单个进程只有一个主线程,当主线程阻塞的时候,整个进程也就阻塞了,无法再去做其它的一些功能了。 2、避免CPU空转,应用程序经常会涉及到RPC,数

知秋一叶 6504

SAP S4HANA F-02报错:更正统一日记账分类账的定制设置

消息号 FINS_ACDOC_CUST201 使用FINS_CUST_CONS_CHK_P去检查公司代码和分类账的设置 提示:过账期间变式为空(分类账 E1/公司代码 7500) 检查了表FINSC_LD_CMP 显示有分类账未分配过账期间变式 解决:后台配置定义分类账和货币类型的设置把过账变式维护下 路径:财务会计→财务会计全局设置→分类账→分类账→定义分类账和货币类型的设置 选中需要维护的分类账双击左侧的“分类账的公司代码设置”,找到对应的公司代码维护上即可。

qq_45068743的博客 6449

Obsidian免费同步全攻略:手把手教你用OneDrive+Remotely Save插件跨设备同步笔记

本文提供了一份详细的Obsidian免费同步方案指南,核心是利用OneDrive云存储与Remotely Save插件实现跨设备笔记同步。文章手把手教学,涵盖插件安装、OneDrive授权配置、桌面端与移动端的同步设置,并解答了常见问题,帮助用户在不依赖官方付费服务的情况下,构建稳定、自主的免费同步工作流。

bash7scripter的博客 851

[Linux系统编程]多线程—互斥

这段代码没有使用互斥锁保护临界区,所以:多线程访问共享变量 ticket,会产生 竞态条件(竞态条件指两个或多个线程试图对共享资源进行操作时,由于线程执行的先后顺序不确定,导致程序的运行结果不可预测或错误的情况。)非原子操作 ticket-- 在高并发下就会引发错误usleep() 增加了被中断的概率,让问题更容易复现结果就是:多卖、错卖、甚至负数票都可能出现✅ 正确的做法:加互斥锁。

Protein_zmm的博客 1218

告别手动标注!PDMS NakiToolkit插件安装与初体验:以Pipeline工具为例

本文详细介绍了PDMS NakiToolkit插件的安装与使用,特别是其Pipeline工具如何通过自动化标注和材料统计功能大幅提升三维工厂设计效率。从环境准备到实战演示,帮助工程师告别繁琐的手动标注工作,实现项目交付周期的大幅缩短。

weixin_30047059的博客 353

【Linux线程】Linux多线程编程:深入理解线程互斥与同步机制

在当今这个数据驱动、高性能计算盛行的时代,多线程编程已经成为软件开发中不可或缺的一部分。Linux,作为开源世界的领头羊,其强大的多线程支持为开发者提供了广阔的舞台,让高并发、高性能的应用得以实现。然而,多线程编程也是一把双刃剑,它在带来性能提升的同时,也引入了线程安全、资源竞争等复杂问题

EterNity_TiMe_的计算机学习之路 2814

博流BL602开发二 环境搭建与固件烧录实战

本文详细介绍了博流BL602 RISC-V芯片开发环境的搭建与固件烧录全流程。从Linux/WSL系统选择、RISC-V工具链配置、SDK获取,到编译首个Wi-Fi示例并生成固件镜像,再到通过命令行或图形化工具完成烧录及串口测试,提供了完整的实战指南和常见问题解决方案。

weixin_29175469的博客 453

Y-Branch and a closed y-branch loop

双臂后面的区域,我们将它的双臂使用一个波导进行了连接,使得它本身形成了一个闭合回路,因此,该结构被称作。它们均是用来对经过它们的光束能量进行分割的一种器件。首先,我们知道一点,在光波导层面,今天给大家介绍一下,什么是。

u011699626的博客 632

【Linux C | 多线程编程】互斥量、信号量、条件变量对比总结

👉本文总结了“互斥量与信号量使用的区别”、“信号量与条件变量使用的区别”、互斥量与条件变量的关系,并给出部分例子解析这些差异的存在。

wkd_007的博客 4265

linux 基于debian/ubuntu AB系统适配(二)-updateEngine移植

其实A/B系统的原理很简单,大部分的工作都集中在uboot上,rootfs只是起到一个辅助的作用,但这个作用也就必不可少的。你会发现在这个其中并没有kernel的参与。

badbayyj的博客 1035

多线程编程——互斥锁

在多线程编程中,互斥锁提供了一种方式,使得一段关键代码(临界区)在同一时刻只能被一个线程执行。

m0_70569293的博客 1511

LangChain面试内容整理-知识点27:LangChain性能调优

LLM应用可能面临响应慢、成本高等性能问题。LangChain提供了一些优化方法和经验来提升性能和效率。

不务正业的猿 328

【AI黑话日日新】什么是AI Infra?

是支撑AI模型开发、训练、推理、部署与规模化运营的,是连接底层算力与上层AI应用的“数字基建”。没有高效的AI Infra,大模型训练、推理与落地都无法高效实现。

专注:太空算力、AI infra、异构调度、大模型成本工程 1114

【探索Linux】P.20(多线程 | 线程互斥 | 互斥锁 | 死锁 | 资源饥饿)

这篇文章涵盖了多线程编程中的关键概念,包括线程互斥、互斥锁、死锁和资源饥饿。在多线程编程中,线程互斥是确保多个线程安全访问共享资源的重要机制。互斥锁是一种常用的同步工具,用于实现线程互斥。然而,如果互斥锁使用不当,可能会导致死锁的发生,即多个线程相互等待对方释放资源而无法继续执行。此外,资源饥饿是另一个并发问题,指某些线程由于无法获取所需资源而陷入无法执行的状态。本文还提供了解决死锁和资源饥饿问题的方法,如预防死锁、避免死锁、检测与解除死锁以及公平性调度和优先级继承等。

Yawesh的博客 2726

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Linux多线程编程中的同步与互斥

本文介绍了线程同步等诸多概念,探讨了如何确保多个线程在共享资源上的正确协作。其次,深入剖析了互斥的概念,以及如何通过互斥锁来实现对临界区的保护,确保线程安全性和数据的一致性。在互斥锁部分,读者将了解互斥锁在Linux环境下的定义、使用方法以及实现原理,并通过示例代码演示了互斥锁的基本用法。随后,文章介绍了条件变量和信号量等其他重要的同步机制,以及可重入性和线程安全性的概念。最后,深入探讨了死锁问题,包括其产生的原因及如何预防和解决。

无敌岩雀的博客 1822

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【Linux】多线程:线程互斥、互斥锁

我们知道一个进程中的多个线程共享进程的地址空间,因此进行线程间的通信是极为容易的,这也就意味着进程中的多个线程可以随意访问进程中的“公共资源”。当一个线程竞争到互斥锁时,首先会将自己al寄存器的内容清零,接着会将互斥量与自己的al寄存器的内容进行交换。1、大部分情况,线程使用的数据都是局部变量,变量的地址空间在线程栈空间内,这种情况,变量归属单个 线程,其他线程无法获得这种变量。2、但有时候,很多变量都需要在线程间共享,这样的变量称为共享变量(如全局区变量),可以通过数据的共享,完成线程之间的交互。

2301_76606232的博客 1886

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Java多线程编程:深入探索线程同步与互斥的实战策略

在现代编程中,多线程环境已经成为提高应用程序性能和响应速度的重要手段。然而多线程编程也带来了复杂的线程安全问题,特别是在多个线程需要访问共享资源时。为了确保线程安全,同步和互斥技术显得尤为关键。本文将详细介绍Java中实现线程同步与互斥的多种方法,并提供相应的代码案例,以帮助开发者更好地理解和应用这些技术。

Rye的博客 2826

QT中的多线程编程

目录 1、Qt中的多线程编程 2、多线程间的同步 3、多线程间的互斥 1、线程锁 2、信号量 4、小结 1、Qt中的多线程编程 Qt中通过QThread直接支持多线程 - QThread是一个跨平台的多线程解决方案 - QThread以简洁易用的方式实现多线程编程 QThread中的关键成员函数 - void run...

洋葱汪的博客 2万+

C++多线程编程 3.互斥量、互斥锁

C++多线程编程的互斥锁相关示例和用法

weixin_59409001的博客 1216

关于c++多线程中的互斥锁mutex

public:int size()// 生产者也就是push的人// 消费者也就是pop的人//允许常量成员函数修改变量mutex mut;其中包含两种锁 mutex queue_lock;//允许常量成员函数修改变量mutex mut;包含一个简单的push函数后面用来讲解混合锁// 自动加锁和解锁// 手动开启关闭// 保证多线程也不会乱出错try// 可以让线程进入等待// 直到队列有空闲位置,避免虚假唤醒// {// return。

qq_46089163的博客 1324

『 Linux 』多线程互斥锁

文章深入分析了互斥锁的原理及其原子性,阐明了互斥锁在多线程同步中的重要性,并展示了如何封装互斥锁以简化其使用。在实际应用中,通过正确使用互斥锁和其他同步机制,可以确保多线程程序的正确性和高效性。最后,文章深入分析了互斥锁的原理及其原子性,阐明了互斥锁在多线程同步中的重要性,并展示了如何封装互斥锁以简化其使用。在实际应用中,通过正确使用互斥锁和其他同步机制,可以确保多线程程序的正确性和高效性。

小侯宝的博客 1318

【多线程编程学习笔记8】使用互斥锁实现线程同步

申明:本学习笔记是在该教程的基础上结合自己的学习情况进行的总结,不是原创,想要看原版的请看C语言中文网的多线程编程(C语言+Linux),该网站有很多好的编程学习教程,尤其是关于C语言的。 在《线程同步机制》一节讲到,实现多线程同步的常用方法有 4 种,互斥锁是其中最简单也最有效地的方法。本节,我们就为您详细讲解互斥锁的具体用法。 互斥锁实现多线程同步的核心思想是:有线程访问进程空间中的公共资源时,该线程执行“加锁”操作(将资源“锁”起来),阻止其它线程访问。访问完成后,该线程负责完成“解锁”操作,将资.

qq_41854911的博客 2448

多线程-互斥

​ 互斥锁是用一种简单的加锁方法来控制对共享资源的访问,互斥锁有两种状态,上锁和解锁,可以把互斥锁看作成某种意义上的全局变量。​ 读写锁与互斥量类似可以实现线程对临界资源的互斥访问,但和互斥量不同的是:互斥量对临界资源的访问是独占的方式;​ 静态:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;​ 在访问共享资源前,首先申请互斥锁,如果互斥锁处于开锁状态,则就可以申请到,并立即占有这个该互斥锁。​ 具体实现: pthread_mutex_lock 函数。

2403_88736889的博客 1090
上一篇: 3、并行计算中的经典问题与挑战
下一篇: 15、并行与分布式系统:架构、优势与性能分析
php55
博客等级 码龄15年 51粉丝 1553原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值