- import random
- import threading
- import time
-
- # Lock = threading.Lock() # 创建一个线程锁。Lock.acquire()表示锁住,线程进入阻塞(暂停)。Lock.release()表示释放(线程继续)
-
- books = 10 # 图书馆书籍数量
- b_rt = 0 # 外面持有数量(借出去的数量)
- day = 0 # 计算天数
-
-
- # 图书馆向外租借书
- def rent_book():
- global b_rt, books
- Lock = threading.Lock() # 建锁
- locked = False # 判断是否锁住,初始未加锁
- while True:
- time.sleep(1)
- check = True if books > 0 else False # 判断是否有书
- if not check: # 没书
- print('图书馆没有书了')
- if not locked: # 没书还未加锁的话,加锁
- Lock.acquire()
- locked = True
- continue # 没有书跳过本次循环(不管有没有加锁)
- if check and locked: # 加锁肯定没书。所以如果有书且加锁了,可以解锁
- Lock.release()
- locked = False
- n = random.randint(1, books) if books > 1 else 1
- n = books if books < n else n
- books -= n
- b_rt += n
- print(f"借出去了{n}本,还剩{books},外面{b_rt}")
-
-
- # 外面持有书籍归还图书馆
- def return_book():
- global b_rt, books
- Lock = threading.Lock()
- locked = False
- while True:
- time.sleep(2)
- check = True if b_rt > 0 else False
- if not check:
- if not locked:
- Lock.acquire()
- locked = True
- continue
- if check and locked:
- Lock.release()
- locked = False
- m = random.randint(1, b_rt) if b_rt > 1 else 1
- books += m
- b_rt -= m
- print(f"归还{m}本,还剩{books},外面{b_rt}")
-
-
- # 图书馆隔段时间会补充一本
- def buyabook():
- global books, day
- day += 1
- print(f"这是第{day}天:\t图书馆有书{books}本\t", end="")
- books += 1
- print("进书1本")
- t = threading.Timer(10, buyabook)
- # Timer对象第一个参数是step间隔,第二个是方法(在方法内可以是方法本身)
- t.start() # 表示调用一次函数会单独启用一个线程
-
-
- t1 = threading.Thread(target=rent_book, args=()) # 创建借书线程
- t2 = threading.Thread(target=return_book, args=()) # 创建还书线程
- # threading.Thread(target=func, args=()) 中target是方法,args是方法的元组形式的参数,
- buyabook() # Timer任务会独立启用一个线程
- t1.start()
- t2.start()
下面面向对象的角度看线程
- import threading
- import time
-
-
- # 创建一个线程类
- class Eat(threading.Thread):
- def __init__(self, name, s: int):
- # 类继承要注意super函数,这里的target可以不写,默认是run。目的是线程启动调用的是run方法
- super(Eat, self).__init__(target=self.run)
- self.name = name
- self.s = s # 定义一个时间间隔
- self.flag = False # 定义一个标记(线程结束标记)
-
- def run(self): # 构建主函数。线程启动后运行的是此方法
- while True:
- time.sleep(self.s)
- print(f"{self.name}在吃饭")
- if self.flag: # 标记为True结束线程
- break
-
- def stop(self): # 定义个方法设置标记为True
- self.flag = True
- print("线程终止")
-
-
- if __name__ == '__main__':
- aron = Eat("aron", 2)
- aron.start() # 线程启动后会持续运行
- # 再实例一个线程
- lily = Eat("lily", 1)
- lily.start()
- # 所有线程都运行再一个进程上,他们单独运行互不影响。除非他们调用了进程上的公共属性
- # 比如你可以把时间设置为进程上的一个变量,例如:
- # step = 2
- # aron = Eat("aron", step)
- # lily = Eat("lily", step)
- print("线程启动后会独立于主线程") # 线程启动后会独立于主线程。下面的内容是独立于被启动的两个线程的
- time.sleep(5)
- aron.stop()
- lily.stop()
那么你可以试试看能不能用面向对象的方法实现生产者消费者模型吧。