经典同步问题及其伪代码实现
1、生产者消费者问题
信号量版本:
# 定义缓冲区大小
bufferSize = 10
# 定义互斥锁和信号量
mutex = Semaphore(1)
full = Semaphore(0)
empty = Semaphore(bufferSize)
# 定义生产者函数
def producer():
while true:
# 生成数据
data = generateData()
# 等待缓冲区不满
empty.P()
mutex.P()
# 将数据放入缓冲区
putDataIntoBuffer(data)
mutex.V()
full.V()
# 定义消费者函数
def consumer():
while true:
# 等待缓冲区不空
full.P()
mutex.P()
# 从缓冲区取出数据
data = getDataFromBuffer()
mutex.V()
empty.V()
# 处理数据
processData(data)
条件变量版本:
# 定义缓冲区大小
bufferSize = 10
# 定义互斥锁和条件变量
mutex = Mutex()
notEmpty = Condition(mutex)
notFull = Condition(mutex)
# 定义缓冲区和指针
buffer = []
inIndex = 0
outIndex = 0
# 定义生产者函数
def producer():
while true:
# 生成数据
data = generateData()
# 获取互斥锁
mutex.lock()
# 等待缓冲区不满
while buffer.length == bufferSize:
notFull.wait()
# 将数据放入缓冲区
buffer[inIndex] = data
inIndex = (inIndex + 1) % bufferSize
# 通知消费者缓冲区不为空
notEmpty.signal()
# 释放互斥锁
mutex.unlock()
# 定义消费者函数
def consumer():
while true:
# 获取互斥锁
mutex.lock()
# 等待缓冲区不为空
while buffer.length == 0:
notEmpty.wait()
# 从缓冲区取出数据
data = buffer[outIndex]
outIndex = (outIndex + 1) % bufferSize
# 通知生产者缓冲区不满
notFull.signal()
# 释放互斥锁
mutex.unlock()
# 处理数据
processData(data)
2、读者写者问题
信号量版本
# 定义读者数量和写者数量
numReaders = 0
numWriters = 0
# 定义互斥锁和信号量
mutex = Semaphore(1)
writeLock = Semaphore(1)
# 定义读者函数
def reader():
while true:
mutex.P() # 获取互斥锁
numReaders += 1
if numReaders == 1: # 如果是第一个读者,获取写者锁
writeLock.P()
mutex.V()
readResource()
mutex.P() # 获取互斥锁
numReaders -= 1
if numReaders == 0: # 如果是最后一个读者,释放写者锁
writeLock.V()
mutex.V()
# 定义写者函数
def writer():
while true:
writeLock.P()
write()
writeLock.V()
条件变量版本
# 定义互斥锁和条件变量
mutex = Mutex()
readersCond = Condition(mutex)
writersCond = Condition(mutex)
# 定义读者函数
def reader():
while true:
# 获取互斥锁
mutex.lock()
# 等待写者释放资源
while numWriters > 0:
readersCond.wait()
numReaders += 1
readersCond.signal()
mutex.unlock()
readResource()
# 获取互斥锁
mutex.lock()
numReaders -= 1
if numReaders == 0:
writersCond.signal()
mutex.unlock()
# 定义写者函数
def writer():
while true:
mutex.lock()
# 等待其他读者和写者释放资源
while numReaders > 0:
writersCond.wait()
# 写入资源
writeResource()
# 通知其他读者和写者
readersCond.signal()
writersCond.signal()
mutex.unlock()
3、哲学家就餐问题
可能有死锁的写法:每个哲学家都拿着左边的筷子,永远都在等右边的筷子。至少一个哲学家的获取筷子的顺序要与其他人不同,以打破环路等待条件:
def getforks() :
if(p == 4):
right[p].P
left[p].P
else:
left[p].P
right[p].P
eat()
left[p].V
right[p].V