【操作系统进程同步】自行车生产线

问题

设自行车生产线上有一只箱子, 其中有N个位置(N≥3), 每个位置可存放一个车架或一个车轮; 又设有三个工人, 其活动分别为:

伪代码

semphore maxFrameNum=N-2,maxWheelNum=N-1,frame=0,wheel=0,empty=N,mutex=1;

worker1(){
	do{
		P(maxFrameNum);
		加工一个车架();
		P(emptyNum);		
		P(mutex);
		车架放入箱子中();
		V(mutex);
		V(frame);
	}while(true)
}

worker2(){
	do{
		P(maxWheelNum);
		加工一个车轮();
		P(emptyNum);
		P(mutex);
		车轮放入箱子中();
		V(mutex);
		V(wheel);
	}while(true)
}

worker3(){
	do{
		P(frame);
		P(mutex);
		从箱子中取一车架;
		V(mutex);
		V(maxFrameNum);
		V(empty);


		P(wheel);
		P(mutex);
		从箱子中取一车轮子;
		V(mutex);
		V(maxWheelNum);
		V(empty);

		P(wheel);
		P(mutex);
		从箱子中取一车轮子;
		V(mutex);
		V(maxWheelNum);
		V(empty);

		组装一辆车();		
	}while(true)
}

Python模拟

import random
import threading
import time

N = 3
maxFrameNum = N - 2
maxWheelNum = N - 1
frame = 0
wheel = 0
empty = N
mutex = 1


def refresh(name):
    if name == 'maxFrameNum':
        return maxFrameNum
    elif name == 'maxWheelNum':
        return maxWheelNum
    elif name == 'frame':
        return frame
    elif name == 'wheel':
        return wheel
    elif name == 'empty':
        return empty
    elif name == 'mutex':
        return mutex


def p(id, item, name):
    print('【woker%s】need a  %s(%d)' % (id, name, item))
    while item <= 0:
        print('【woker%s】is waiting for %s' % (id, name))
        time.sleep(random.random())
        item = refresh(name)
    global maxWheelNum
    global maxFrameNum
    global wheel
    global empty
    global mutex
    global frame
    if name == 'maxFrameNum':
        maxFrameNum -= 1
    elif name == 'maxWheelNum':
        maxWheelNum -= 1
    elif name == 'frame':
        frame -= 1
    elif name == 'wheel':
        wheel -= 1
    elif name == 'empty':
        empty -= 1
    elif name == 'mutex':
        mutex -= 1


def v(id, item, name):
    global maxWheelNum
    global maxFrameNum
    global wheel
    global empty
    global mutex
    global frame
    if name == 'maxFrameNum':
        maxFrameNum += 1
    elif name == 'maxWheelNum':
        maxWheelNum += 1
    elif name == 'frame':
        frame += 1
    elif name == 'wheel':
        wheel += 1
    elif name == 'empty':
        empty += 1
    elif name == 'mutex':
        mutex += 1
    print('【woker%s】release  %s' % (id, name))


def printMsg():
    print('maxFrameNum:%s,maxWheelNum:%s,frame:%s,wheel:%s,empty:%s' % (maxFrameNum, maxWheelNum, frame, wheel, empty))


def woker1():
    while True:
        time.sleep(random.random() * 4)
        p(1, maxFrameNum, 'maxFrameNum')
        print('【woker1】is making a frame')
        p(1, empty, 'empty')

        p(1, mutex, 'mutex')
        print('【woker1】is putting a frame into the box')
        v(1, mutex, 'mutex')

        v(1, frame, 'frame')
        printMsg()


def woker2():
    while True:
        time.sleep(random.random() * 2)
        p(2, maxWheelNum, 'maxWheelNum')
        print('【woker2】is making a wheel')
        p(2, empty, 'empty')

        p(2, mutex, 'mutex')
        print('【woker2】is putting a wheel into the box')
        v(2, mutex, 'mutex')

        v(2, wheel, 'wheel')

        printMsg()


def woker3():
    while True:
        time.sleep(random.random() * 4)
        p(3, frame, 'frame')
        p(3, mutex, 'mutex')
        print('【woker3】is getting a frame from the box')
        v(3, mutex, 'mutex')
        v(3, maxFrameNum, 'maxFrameNum')
        v(3, empty, 'empty')
        printMsg()
        p(3, wheel, 'wheel')
        p(3, mutex, 'mutex')
        print('【woker3】is getting a wheel from the box')
        v(3, mutex, 'mutex')
        v(3, maxWheelNum, 'maxWheelNum')
        v(3, empty, 'empty')
        printMsg()
        p(3, wheel, 'wheel')
        p(3, mutex, 'mutex')
        print('【woker3】is getting a wheel from the box')
        v(3, mutex, 'mutex')
        v(3, maxWheelNum, 'maxWheelNum')
        v(3, empty, 'empty')
        printMsg()
        print('【woker3】is making a car')


if __name__ == '__main__':
    w1 = threading.Thread(target=woker1)
    w2 = threading.Thread(target=woker2)
    w3 = threading.Thread(target=woker3)
    w1.start()
    w2.start()
    w3.start()

最终效果

 

 总结

1. PV操作中需要修改全局变量,而Python修改全局变量需要使用关键字global声明一下,若使用C++写会比较方便,直接使用指针就可以修改全局变量了。

2. maxFrameNum初始值设置为N-1也可以保证不产生死锁。

3. 老师的PPT中没有使用mutex变量来访问临界资源(箱子),个人感觉有必要加上mutex。(若有不同想法,欢迎留言讨论~

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值