线程,进程,协程
1.线程
特点:占用资源少,效率一般
模块:threading and _thread
#示例1:实现多线程
import _thread
import time
def sing(delaye):
for i in range(5):
time.sleep(delaye)
print("============我在唱歌==================")
def dance(delaye):
for i in range(5):
time.sleep(delaye)
print("============我在跳舞==================")
def main():
# 创建线程
_thread.start_new_thread(sing, (1,))
_thread.start_new_thread(dance, (1,))
if __name__ == '__main__':
try:
main()
except:
print("无法创建线程")
while 1:
pass
# run结果
"""
============我在跳舞==================
============我在唱歌==================
============我在跳舞==================
============我在唱歌==================
============我在跳舞==================
============我在唱歌==================
============我在跳舞==================
============我在唱歌==================
"""
# 示例2:实现多线程的同步通信
import time
import threading
import queue
exitFlag = 0
# 线程类:继承threading类
class Mythread(threading.Thread):
def __init__(self, name, threadId, q):
threading.Thread.__init__(self)
self.threadId = threadId
self.name = name
self.q = q
def run(self):
print("开始进程:" + self.name)
process_dadta(self.name, self.q)
print("退出线程" + self.name)
def process_dadta(threaName, q):
while not exitFlag:
# 上锁
queueLock.acquire()
if not workqueue.empty():
data = q.get()
# 解锁
queueLock.release()
print("%s processing %s" % (threaName, data))
else:
# 解锁
queueLock.release()
time.sleep(1)
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
# 锁
queueLock = threading.Lock()
# 创建队列对象:只储存10个消息
workqueue = queue.Queue(10)
threadId = 1
# 储存线程对象的列表
threads = []
for tName in threadList:
# 创建线程类对象
thread = Mythread(tName, threadId, workqueue)
# 开始运行线程
thread.start()
threads.append(thread)
threadId += 1
# 上锁
queueLock.acquire()
for word in nameList:
workqueue.put(word)
# 解锁
queueLock.release()
while not workqueue.empty():
pass
exitFlag = 1
for t in threads:
t.join()
print("退出主线程")
# run结果
"""
开始进程:Thread-1
开始进程:Thread-2
开始进程:Thread-3
Thread-2 processing One
Thread-3 processing Two
Thread-1 processing Three
Thread-2 processing Four
Thread-3 processing Five
退出线程Thread-2
退出线程Thread-1退出线程Thread-3
退出主线程
"""
"""
lock = threading.Lock()
lock.acquire()
....
lock.release()
这就是实现线程同步的基本操作
"""
# 示例3:线程同步
import threading
nums = 100
def add1(threadLock):
global nums
threadLock.acquire()
for i in range(1000000):
nums += 1
threadLock.release()
print(nums)
def add2(threadLock):
global nums
threadLock.acquire()
for i in range(1000000):
nums += 1
threadLock.release()
print(nums)
def main():
threadLock = threading.Lock()
t1 = threading.Thread(target=add1,args=(threadLock,))
t2 = threading.Thread(target=add2,args=(threadLock,))
t1.start()
t2.start()
t1.join()
t2.join()
if __name__ == '__main__':
main()
run 结果
"""
1000100
2000100
"""
# 示例4:线程通信:多线程copy文件
import time
import threading
import queue
import os
def copy_file(q, file_name, aim_copy_file):
fo = open(aim_copy_file+'/'+file_name,'rb')
content = fo.read()
fo.close()
fo_copy = open(aim_copy_file+'[复件]'+'/'+file_name,'wb')
fo_copy.write(content)
fo_copy.close()
q.put(file_name)
def main():
# 1.获取要复制的文件的文件夹名
aim_file_name = input("请输入您想要复制的文件夹名: ")
# 2.创建储存复制文件的文件夹
try:
os.mkdir(aim_file_name + '[复件]')
except:
pass
# 3.获取该文件夹里所有文件的名称
file_names = os.listdir(aim_file_name)
# 4.创建队列
q = queue.Queue(100)
# 5.创建线程列表
threads = list()
# 6.创建下线程
for file_name in file_names:
t = threading.Thread(target=copy_file, args=(q, file_name, aim_file_name))
t.start()
threads.append(t)
# for t in threads:
# t.join()
while True:
if q.empty():
break
else:
data = q.get()
print("已完成复制的文件:%s"%data)
if __name__ == '__main__':
start = time.time()
main()
end = time.time()
print("用时:%0.5f s"%(end-start))
2.进程
特点:占用资源多,效率低
模块:multiprocessing
# 示例1:进程的创建与通信
import multiprocessing
import time
def download(q):
date = [11, 22, 33, 44, 55]
for i in date:
q.put(i)
print("数据下载完成!")
def data_chuli(q):
write_data = list()
while True:
if not q.empty():
date = q.get()
write_data.append(date)
else:
break
print(write_data)
def main():
# 创建队列对象
q = multiprocessing.Queue(5)
p1 = multiprocessing.Process(target=download,args=(q,))
p2 = multiprocessing.Process(target=data_chuli,args=(q,))
p1.start()
p2.start()
if __name__ == '__main__':
main()
# 示例2:多进程和进程池实现copy文件
import os
import multiprocessing
import time
def copy_file(q, file_name, old_file_name,):
targe_file_copy = open(old_file_name + '/' + file_name, 'rb')
content = targe_file_copy.read()
targe_file_copy.close()
targe_file = open(old_file_name + '[复件]' + '/' + file_name, 'wb')
targe_file.write(content)
targe_file.close()
q.put(file_name)
def main():
# 1.获取输入的要复制的文件夹的名称
old_file_name = input("输入您想复制的文件名")
# 2.创建储存复制的文件的文件夹
try:
os.mkdir(old_file_name + '[复件]')
except:
print("文件已经创建")
# 3.获取该文件夹的所有文件名称
file_names = os.listdir(old_file_name)
q = multiprocessing.Manager().Queue()
# 4.创建进程池
po = multiprocessing.Pool(5)
for file_name in file_names:
# 添加到进程池里
po.apply_async(copy_file, args=(q, file_name, old_file_name,))
po.close()
copy_file_number = 0
# po.join()
while True:
data = q.get()
copy_file_number += 1
print("\r完成进度:%0.2f" %(copy_file_number*100/len(file_names)),end=' ')
if copy_file_number >= len(file_names):
break
if __name__ == '__main__':
start = time.time()
main()
end = time.time()
print("用时:%0.5f s" % (end - start))
3.协程
特点:占用资源小,效率高
模块:greenlet,gevent
# 示例1:通过yield关键字实现协程基本原理
def fun1():
while True:
print("-------1-----------")
yield
def fun2():
while True:
print("-------2-----------")
yield
def main():
y1 = fun1()
y2 = fun2()
while True:
next(y1)
next(y2)
if __name__ == '__main__':
main()
# 示例2:greenlet
import greenlet
def fun1():
while True:
print("-------1-----------")
y2.switch()
def fun2():
while True:
print("-------2-----------")
y1.switch()
y1 = greenlet.greenlet(fun1)
y2 = greenlet.greenlet(fun2)
y1.switch()
#示例3:gevent
from greenlet import greenlet
import gevent
import time
def f1(n, number):
for i in range(n):
print("this is number = %d" % number)
print(gevent.getcurrent(), i)
gevent.sleep(0.5)
def f2(n, number):
for i in range(n):
print("this is number = %d" % number)
print(gevent.getcurrent(), i)
gevent.sleep(0.5)
def f3(n, number):
for i in range(n):
print("this is number = %d" % number)
print(gevent.getcurrent(), i)
gevent.sleep(0.5)
g1 = gevent.spawn(f1, 5, 1)
g2 = gevent.spawn(f2, 5, 2)
g3 = gevent.spawn(f3, 5, 3)
g1.join()
g2.join()
g3.join()
#示例4:
from greenlet import greenlet
import gevent
import time
from gevent import monkey
# 可以讲将other modlue.xxx====>gevent.xx
monkey.patch_all()
def f1(n, number):
for i in range(n):
print("this is number = %d" % number)
print(gevent.getcurrent(), i)
time.sleep(0.5)
def f2(n, number):
for i in range(n):
print("this is number = %d" % number)
print(gevent.getcurrent(), i)
time.sleep(0.5)
def f3(n, number):
for i in range(n):
print("this is number = %d" % number)
print(gevent.getcurrent(), i)
gevent.sleep(0.5)
g1 = gevent.spawn(f1, 5, 1)
g2 = gevent.spawn(f2, 5, 2)
g3 = gevent.spawn(f3, 5, 3)
g1.join()
g2.join()
g3.join()