Skip to content

并发与同步 ​

并发同步(Concurrency Synchronization)是协调多个线程或进程的执行顺序,让它们访问共享资源(变量、数据结构、文件)时不会产生数据冲突。关键概念:

关键概念 ​

  1. 竞态条件(Race Condition):当两个或多个线程或进程并发地访问和修改同一个共享资源,并且最终结果依赖于访问的顺序时,就会发生竞态条件。竞态条件可能导致不一致的数据或未定义的行为。

  2. 临界区(Critical Section):是指在并发程序中访问共享资源的代码块。在任何时候,只能有一个线程执行临界区中的代码,以防止数据冲突。

  3. 互斥(Mutual Exclusion):指的是确保某一时刻只有一个线程可以进入临界区,避免多个线程同时执行临界区代码。互斥可以通过锁(Lock)机制来实现。

同步技术 ​

  1. 锁(Lock):锁是一种最基本的同步机制。通过加锁和解锁操作,确保在同一时刻只有一个线程可以访问共享资源。常见的锁类型有互斥锁(Mutex)和读写锁(Read-Write Lock)。

  2. 信号量(Semaphore):信号量是一种更高级的同步机制,用于控制对共享资源的访问。信号量可以用来限制同时访问资源的线程数量。二进制信号量(Binary Semaphore)类似于互斥锁,而计数信号量(Counting Semaphore)可以允许多个线程同时访问资源。

  3. 条件变量(Condition Variable):条件变量用于阻塞线程直到特定的条件变为真。它通常与互斥锁一起使用,以在等待条件时释放锁,并在条件满足时重新获取锁。

  4. 自旋锁(Spinlock):自旋锁是一种忙等待的锁机制,线程在等待锁释放时不断循环检查锁的状态。自旋锁适用于等待时间很短的场景,因为它避免了线程上下文切换的开销。

  5. 屏障(Barrier):屏障是一种同步机制,允许多个线程在特定点汇合和同步。只有当所有线程都到达屏障点时,线程才能继续执行。

  6. 原子操作(Atomic Operations):原子操作是不可分割的操作,保证在执行过程中不会被其他线程中断。常见的原子操作有原子加减(Atomic Increment/Decrement)和交换(Atomic Swap)。

常见的并发同步问题 ​

  1. 死锁(Deadlock):当两个或多个线程互相等待对方持有的资源而无法继续执行时,就会发生死锁。避免死锁的方法包括资源分配策略、避免循环等待、定时锁等。

  2. 饥饿(Starvation):当某个线程长时间无法获得所需的资源,导致无法继续执行时,就会发生饥饿。公平锁和优先级调度可以减少饥饿的发生。

  3. 活锁(Livelock):当线程不断尝试解决冲突,但总是相互干扰无法继续执行时,就会发生活锁。合理的重试机制和随机等待时间可以减少活锁的发生。

竞态条件靠锁和原子操作防,死锁靠资源分配顺序和定时锁解,饥饿靠公平锁,活锁靠合理的重试间隔——问题的解法都在对应小节里。

参考资料 ​

同层页面 ​

相关页面 ​

Hello Golang