MST

星途 面试题库

面试题:并发与同步:互斥锁在多线程环境下如何保证线程安全

假设你正在开发一个多线程程序,其中多个线程会访问并修改同一个共享资源。请描述如何使用互斥锁来确保这个共享资源的线程安全,并给出一个简单的代码示例(语言不限)。同时说明在代码中使用互斥锁可能会出现哪些问题,如何避免?
47.3万 热度难度
操作系统并发与同步

知识考点

AI 面试

面试题答案

一键面试

使用互斥锁确保共享资源线程安全的描述

互斥锁(Mutex,即Mutual Exclusion的缩写)是一种用于多线程编程中保护共享资源的同步原语。当一个线程获取到互斥锁时,其他线程就无法获取该锁,直到持有锁的线程释放它。这样就保证了在同一时间只有一个线程能够访问并修改共享资源,从而确保线程安全。

代码示例(以Python为例)

import threading

# 共享资源
shared_variable = 0
# 创建互斥锁
mutex = threading.Lock()

def increment():
    global shared_variable
    for _ in range(100000):
        # 获取互斥锁
        mutex.acquire()
        try:
            shared_variable += 1
        finally:
            # 释放互斥锁
            mutex.release()

# 创建多个线程
threads = []
for _ in range(10):
    t = threading.Thread(target=increment)
    threads.append(t)
    t.start()

# 等待所有线程完成
for t in threads:
    t.join()

print("Final value of shared variable:", shared_variable)

使用互斥锁可能出现的问题及避免方法

  1. 死锁
    • 问题描述:当两个或多个线程相互等待对方释放锁时,就会发生死锁。例如,线程A持有锁1并等待锁2,而线程B持有锁2并等待锁1。
    • 避免方法
      • 按照固定顺序获取锁。例如,总是先获取锁1,再获取锁2,避免交叉获取。
      • 使用超时机制。在获取锁时设置一个超时时间,如果在规定时间内未能获取到锁,则放弃获取并进行相应处理。
  2. 性能问题
    • 问题描述:过多的锁竞争会导致性能下降,因为线程在等待锁时会被阻塞,无法执行其他任务。
    • 避免方法
      • 尽量缩短锁的持有时间,只在真正访问和修改共享资源的代码段加锁。
      • 减少锁的粒度,将大的共享资源拆分成多个小的部分,每个部分使用单独的锁,这样不同线程可以同时访问不同部分的资源。
  3. 饥饿
    • 问题描述:某些线程可能长时间无法获取到锁,因为其他线程频繁获取和释放锁。
    • 避免方法
      • 使用公平锁(如果编程语言或库支持),公平锁会按照请求顺序分配锁,避免某些线程被一直阻塞。
      • 定期提升低优先级线程的优先级,确保每个线程都有机会获取锁。