多任务指的是在同一时间不同任务需要同时进行的场景,比如边听歌边刷题,边看电视边吃饭…
import time
# 吃饭
def Eat():
for i in range(4):
print('eating...')
time.sleep(1)
# 看电视
def Watch():
for i in range(4):
print('watching...')
time.sleep(1)
if __name__ == '__main__':
Eat()
Watch()
# --结果:--
# eating...
# eating...
# eating...
# eating...
# watching...
# watching...
# watching...
# watching...
嗯,,,但这是同时进行吗?仔细一想他们是有先后顺序的吧。
import threading
import time
def speak():
# 子线程
print('A先说!')
time.sleep(1)
if __name__ == '__main__':
for i in range(5):
t = threading.Thread(target=speak)
t.start()
print('B有话要说!')
结果(执行了几十次吧)出现了以下三种情况:
在t.start()后面添加
t.join()
时间会按照先后顺序来了,但是结果确实只有第三种了,剩下的setDaemon()加了与没加效果一样
有事我们需要查看有哪些进程运行了可以使用:threading.enumerate()
例如:
import threading
import time
def speak():
# 子线程
print('A先说!')
time.sleep(1)
if __name__ == '__main__':
for i in range(5):
t = threading.Thread(target=speak)
t.setDaemon(True)
t.start()
print('B有话要说!')
print(threading.enumerate())
print('共有'+str(len(threading.enumerate()))+'个线程...')
# ---结果:---
# A先说!
# # A先说!
# # A先说!
# # A先说!
# # A先说!B有话要说!
# # [<_MainThread(MainThread, started 10900)>, , , , , ]
# #
# # 共有6个线程...
当然,为了简化子线程的创建,我们通过类的继承来实现,而我们所需要实现的内容,都在run方法之中进行重写。
import threading
import time
class MyThread(threading.Thread):
# 继承threading.Thread类创建子线程
def __init__(self,name):
super().__init__(name=name)
def run(self):
for i in range(3):
print('我是{}{}'.format(self.name,i))
if __name__ == '__main__':
thread = MyThread('子线程')
thread.start()
# --结果:--
# 我是子线程0
# 我是子线程1
# 我是子线程2
threading.Thread(target=test, args=(num,))
import threading
import time
num = 0
def Thread1(nums):
global num
for i in range(nums):
num += 1
print('Thread1---{}'.format(num))
def Thread2(nums):
global num
for i in range(nums):
num += 1
print('Thread1---{}'.format(num))
if __name__ == '__main__':
t1 = threading.Thread(target=Thread1, args=(1000000,))
t2 = threading.Thread(target=Thread2, args=(1000000,))
t1.start()
t2.start()
time.sleep(2)
print('main---{}'.format(num))
# --结果:--
# Thread1---1074807
# Thread1---1400032
# main---1400032
以上结果显示,输出的结果不为我们所认为正确的答案,其原因就是资源竞争,那么何谓资源竞争?
import threading
# 创建锁
mutex = threading.Lock()
# 锁定锁
mutex.acquire()
# 解锁
mutex.release()
import threading
import time
# 创建锁A、B
mutexA = threading.Lock()
mutexB = threading.Lock()
class thread1(threading.Thread):
def run(self):
mutexA.acquire()
print('thread1--A上锁成功')
time.sleep(1)
mutexB.acquire()
print('thread1--B上锁成功')
mutexA.release()
mutexB.release()
class thread2(threading.Thread):
def run(self):
mutexB.acquire()
print('thread2--B上锁成功')
time.sleep(1)
mutexA.acquire()
print('thread2--A上锁成功')
mutexB.release()
mutexA.release()
if __name__ == '__main__':
T1 = thread1()
T2 = thread2()
T1.start()
T2.start()
# --结果:--
# thread1--A上锁成功
# thread2--B上锁成功
相信大家对于数据结构中的栈和队列都不陌生吧,栈在这里我们不做介绍,我们就看看队列Queue
方法 | 功能 |
---|---|
empty() | 判断队列是否为空 |
full() | 判断队列是否满 |
put() | 向队列中放入元素 |
get() | 从队列中取出元素 |
qsize() | 获取队列长度 |
from queue import Queue
q = Queue(3)
# 判断队列是否为空
print(q.empty()) #True
# 判断队列是否满了
print(q.full()) #False
# 放入元素
q.put(111)
q.put(444)
q.put(666)
# 设置timeout或put_nowait当队列满了直接跳出
# q.put(886,timeout=2)
# 获取队列长度
print(q.qsize()) #3
# 获取元素
print(q.get()) #111
print(q.get()) #444
print(q.get()) #666
例如实现以下会话:
老师:小明?
小明:到。
老师:给我讲讲同步线程的实现吧!
小明:我…试试吧!
代码如下:
import threading
class XiaoMing(threading.Thread):
def __init__(self,cond):
super().__init__(name='小明')
self.cond = cond
def run(self):
self.cond.acquire()
self.cond.wait()
print('{}:在。'.format(self.name))
self.cond.notify()
self.cond.wait()
print('{}:我...试试吧!'.format(self.name))
self.cond.notify()
self.cond.release()
class Teacher(threading.Thread):
def __init__(self,cond):
super().__init__(name='老师')
self.cond = cond
def run(self):
self.cond.acquire()
# self.cond.wait()
print('{}:小明?'.format(self.name))
self.cond.notify()
self.cond.wait()
print('{}:给我讲讲同步线程的实现吧!'.format(self.name))
self.cond.notify()
self.cond.release()
if __name__ == '__main__':
cond = threading.Condition()
teacher = Teacher(cond)
xiaoming = XiaoMing(cond)
xiaoming.start()
teacher.start()
ps:一定要把先进行的对话放在后面启动。否则会导致堵塞。