首页 > 其他分享 >【操作系统】2.并发控制

【操作系统】2.并发控制

时间:2024-10-30 23:08:40浏览次数:1  
标签:std 控制 操作系统 信号量 并发 线程 include

并发控制(Concurrency Control)是指在多线程或多进程环境中,确保多个操作在共享资源上的访问不会发生冲突或产生不一致的情况。并发控制的核心目标是在允许并发操作的同时,保证系统的正确性、数据的一致性和完整性。

在并发环境下,不同的线程或进程可能会同时访问共享资源(例如变量、文件或数据库记录)。若没有适当的并发控制,可能会发生数据竞争(Race Condition)或死锁(Deadlock)等问题,导致系统出现错误或不稳定的状态。因此,并发控制是实现多线程或分布式系统时必须考虑的问题。

并发控制的主要问题

  1. 数据竞争(Race Condition)
    当多个线程同时读取和修改共享变量,且访问顺序不确定时,可能会导致数据竞争。例如,一个线程正在写数据,另一个线程正在读取数据,读到的可能是不完整或错误的结果。

  2. 死锁(Deadlock)
    当多个线程因相互等待对方释放资源而无限期地等待时,就会产生死锁。例如,线程A持有资源X并等待资源Y,而线程B持有资源Y并等待资源X,最终导致两个线程都无法继续。

  3. 资源饥饿(Starvation)
    某些线程由于得不到所需资源而一直无法执行,称为资源饥饿。例如,优先级较低的线程可能由于高优先级线程的持续占用而一直得不到运行机会。

  4. 数据不一致
    由于缺乏正确的并发控制,可能导致多个线程读取和写入共享数据,最终数据出现不一致的问题。例如,多个线程同时更新一个计数器,可能会导致最终计数不准确。


并发控制的常见机制

并发控制的核心是通过协调多个线程或进程对共享资源的访问,确保操作的正确性。以下是常见的并发控制机制:

1. 锁(Lock)

锁是并发控制中最常用的工具,用于限制同一时间内只有一个线程访问某个资源。常见的锁类型包括:

  • 互斥锁(Mutex):一种互斥机制,确保同一时间只有一个线程访问共享资源。其他线程必须等待,直到锁被释放。

      #include <iostream> #include <thread> #include <mutex> std::mutex mtx; void printSafe(const std::string& message) {   std::lock_guard<std::mutex> lock(mtx); // 自动加锁和解锁   std::cout << message << std::endl; }
  • 读写锁(Read-Write Lock):允许多个线程同时读取数据,但当一个线程写入数据时,其它读写线程都必须等待。

  • 自旋锁(Spin Lock):一种简单的锁机制,线程在等待锁时会持续检查锁的状态,不进入休眠,适用于短时间的锁等待场景。

2. 信号量(Semaphore)

信号量是一种控制线程数目的同步机制。信号量有一个计数器,用于记录当前可用的资源数:

  • 计数信号量:可以设置允许的最大并发线程数,适合控制对有限资源的访问。
  • 二元信号量:与互斥锁相似,但可以实现更复杂的同步机制。
    #include <iostream>   #include <thread>   #include <semaphore.h> // C++20 中引入   std::counting_semaphore<1> semaphore(1);   void sharedFunction() {      semaphore.acquire(); // 获取信号量      // 临界区代码      std::cout << "Executing critical section" << std::endl;      semaphore.release(); // 释放信号量   }

3. 条件变量(Condition Variable)

条件变量是一种同步机制,允许线程在特定条件下等待。条件变量通常与互斥锁一起使用,以便线程在条件不满足时进入等待状态,条件满足时被唤醒。

    #include <iostream>   #include <thread>   #include <condition_variable>   #include <mutex>       std::mutex mtx;   std::condition_variable cv;   bool ready = false;       void waitFunction() {       std::unique_lock<std::mutex> lock(mtx);       cv.wait(lock, [] { return ready; }); // 等待条件满足       std::cout << "Proceeding after condition met" << std::endl;   }   void signalFunction() {      {         std::lock_guard<std::mutex> lock(mtx);         ready = true; // 设置条件      }      cv.notify_all(); // 唤醒等待线程   }

4. 原子操作(Atomic Operation)

原子操作是一种不可中断的操作,即使在多线程环境下,也不会被其他线程干扰。C++提供std::atomic来支持原子操作,可以有效避免数据竞争问题。

    #include <iostream>   #include <atomic>   #include <thread>   std::atomic<int> counter(0);   void increment() {      counter.fetch_add(1); // 原子性增加1   }

并发控制的应用场景

  • 银行账户系统:确保多个操作不会同时修改同一个账户的数据,防止因数据竞争导致的错误。
  • 生产者-消费者模型:使用条件变量或信号量来控制生产者和消费者对缓冲区的访问,防止数据丢失或重复读取。
  • 数据库系统:在多事务并发操作下确保数据的一致性和完整性,常使用锁和日志等方式实现并发控制。

并发控制的选择

  • 锁机制适用于需要严格控制访问顺序的情况,但需小心避免死锁。
  • 信号量更适合资源有限的场景,如限制同时访问某资源的线程数。
  • 原子操作适用于简单的共享变量操作,代价低且操作简单,但仅限于一些基本操作。
  • 条件变量适用于等待特定条件的场景,能够实现较高的线程协调效率。

标签:std,控制,操作系统,信号量,并发,线程,include
From: https://www.cnblogs.com/luckyyys/p/18516810

相关文章

  • Oracle 第14章:并发控制
    在Oracle数据库中,并发控制是一个关键概念,因为它确保了多个用户或事务可以同时访问数据库而不干扰彼此的工作。并发问题主要出现在多用户环境中,当多个事务试图同时修改相同的数据时可能发生数据不一致的问题。并发问题及解决方案并发问题:脏读(DirtyReads):一个事务读取了另......
  • 16.1 并发编程基础——Java多线程
    16.1并发编程基础——Java多线程16.1.1 引言Java语言的一个重要特点是内在支持多线程的程序设计。多线程的程序设计具有广泛的应用。线程的概念来源于操作系统进程的概念。进程是一个程序关于某个数据集的一次运行。也就是说,进程是运行中的程序,是程序的一次运行活动。线......
  • Proportional Controller比例控制器
    ProportionalController比例控制器通过接收外部的控制信号,将这些信号转换为相应的机械位移或力,进而驱动比例阀的阀芯移动,从而改变阀口的开度,实现对压力、流量等参数的连续、按比例控制。连续控制:与开关控制相比,比例阀控制器能够实现对压力、流量等参数的连续、无级调节。高......
  • 控制柜的分类
    通用电气GE 模块IC693CPU323LT 通用电气GE 模块IC693CPU323RR控制柜的分类多种多样,根据不同的功能和用途,可以分为以下几种主要类型:一、按功能和用途分类动力控制柜:主要用于控制电机、变频器、发电机等动力设备。它能够实现对电机的启停、调速、正反转等控制功能,同时具备......
  • 程序化交易策略里,风险管理和心态控制怎样平衡?
    Python股票接口实现查询账户,提交订单,自动交易(1)Python股票程序交易接口查账,提交订单,自动交易(2)股票量化,Python炒股,CSDN交流社区>>>风险识别与评估程序化交易面临多种风险,包括市场风险、技术风险等。市场风险源于市场波动,价格变动可能使策略失效。技术风险则与交易系统......
  • InnoDB存储引擎、多版本并发控制(MVCC)简介、Redis简介
    (一)InnoDB存储引擎InnoDB是MySQL最常用的存储引擎之一,有支持事务处理、行级锁定和外键约束等高级功能而著称。1、InnoDB架构物理结构表空间:InnoDB的数据存储空间在表空间中,表空间可以分为系统表空间、文件表空间和通用表空间。系统表空间:默认存储在ibdata1文件中,包含系统......
  • 路由控制技术
    路由控制概述定义与目的路由控制是网络管理的核心组成部分,旨在优化网络资源利用并提高整体性能。通过精心设计的策略,管理员可以实现对数据流的精细控制,确保关键业务获得优先处理,同时有效防止未经授权的访问和潜在的数据泄露风险。这种控制不仅能提升网络效率,还能显著增强......
  • 【项目实战】远程信息处理控制单元(TCU),集成了多种通信技术,如蜂窝网络、Wi-Fi、蓝牙等,使
    一、TCU是什么?TCU,远程信息处理控制单元(TelematicsControlUnit)TCU,是车辆中用于实现远程信息处理功能的关键组件。TCU,集成了多种通信技术,如蜂窝网络、Wi-Fi、蓝牙等,使得车辆能够与外部系统进行数据交换和通信。二、TCU支持的各种应用和服务TCU,在车联网中扮演着重要角色......
  • 面试官:Spring Boot 控制层中,@Service 可以完全替代 @Controller 吗?90% 都会答错!
    作者:毅航来源:juejin.cn/post/7393533304505204787在SpringBoot开发中,@Controller和@Service基本上是日常开发中使用的最频繁的两个注解。但你有没考虑过@Service代替@Controller注解来标注到控制层的场景?换言之,经过@Service标注的控制层能否实现将用户请求分发到服务层的功能?......
  • 【花雕学编程】Arduino动手做(237)---使用 ESP32 V1 Rev1 自身的热点来创建一个简易的 H
    37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来——小小的......