"""
Author:黄骏捷
Date:2019-10-10
Python实现并发并发编程主要有3种方式:多进程,多线程,多进程+多线程
Unix和Linux提供了fork()系统调用来创建进程
windows系统没用fork调用,可以使用multiprocessing模块的Process类来创建子进程
使用多线程和不使用多线程的区别
#无多线程
from random import randint
from time import sleep, time
def download_task(filename):
print('开始下载%s...' % filename)
time_to_download = randint(5, 10)
sleep(time_to_download)
print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
def main():
start = time()
download_task('Python入门到入土.pdf')
download_task('Peking Hot.avi')
end = time()
print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
main()
"""
"""
多线程1
from multiprocessing import Process
from os import getpid
from random import randint
from time import sleep, time
def download_task(filename):
print('启动下载进程,进程号[%d].' % getpid())
print('开始下载%s...' % filename)
time_to_download = randint(5,10)
sleep(time_to_download)
print('%s下载完成!耗费%d秒' % (filename,time_to_download))
def main():
start = time()
#Process类创建进程对象,Target参数:传入一个函数,args:函数的参数
p1 = Process(target=download_task,args=('Python从入门到住院.pdf',))
p1.start()
p2 = Process(target=download_task,args=('Peking Hot.avi',))
p2.start()
p1.join()
p2.join()
end = time()
print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
main()
"""
#多线程2 subprocess模块中的类和函数来创建和启动子进程,然后通过管道来和子进程通信
#一个输出Ping 一个输出Pong 加起来输出
"""
from multiprocessing import Process
from time import sleep
counter = 0
def sub_task(string):
global counter
while counter < 10:
print(string,end='',flush=True)
counter += 1
sleep(0.01)
def main():
Process(target=sub_task,args=('Ping',)).start()
Process(target=sub_task,args=('Pong',)).start()
if __name__ == '__main__':
main()
#输出 PingPongPingPongPingPongPingPongPingPongPingPongPingPongPingPongPingPongPingPong
# 当我们程序创建进程时,子进程复制了父进程及其所有数据结构,每个子进程拥有自己独立的内存空间,各有一个counter变量
"""
#多线程3 thread模块(现在名_thread)过于底层,很多功能没用,推荐使用threading模块
"""
from random import randint
from threading import Thread
from time import time, sleep
def download(filename):
print('开始下载%s...' % filename)
time_to_download = randint(5, 10)
sleep(time_to_download)
print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
def main():
start = time()
t1 = Thread(target=download, args=('Python从入门到住院.pdf',))
t1.start()
t2 = Thread(target=download, args=('Peking Hot.avi',))
t2.start()
t1.join()
t2.join()
end = time()
print('总共耗费了%.3f秒' % (end - start))
if __name__ == '__main__':
main()
"""
#通过继承Thread类来创建自定义的线程类
from time import sleep, time
from random import randint
from threading import Thread
class DownloadTask(Thread):
def __init__(self,filename):
super().__init__()
self._filename = filename
def run(self):
print('开始下载%s...' % self._filename)
time_to_download = randint(5,10)
sleep(time_to_download)
print('%s下载完成!耗费了%d秒' % (self._filename,time_to_download))
def main():
start = time()
t1 = DownloadTask('Python从入门到住院.pdf')
t1.start()
t2 = DownloadTask('Peking Hot.avi')
t2.start()
t1.join()
t2.join()
end = time()
print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
main()
"""
多个线程可以共享内存空间,因此多个线程间的通信相对简单,设置一个全局变量,
多个线程共享同一个变量(称为 临界资源),很可能产生不可控结果从而导致程序失效甚至崩溃
from time import sleep
from threading import Thread
class Account(object):
def __init__(self):
self._balance = 0
def deposit(self, money):
# 计算存款后的余额
new_balance = self._balance + money
# 模拟受理存款业务需要0.01秒的时间
sleep(0.01)
# 修改账户余额
self._balance = new_balance
@property
def balance(self):
return self._balance
class AddMoneyThread(Thread):
def __init__(self, account, money):
super().__init__()
self._account = account
self._money = money
def run(self):
self._account.deposit(self._money)
def main():
account = Account()
threads = []
# 创建100个存款的线程向同一个账户中存钱
for _ in range(100):
t = AddMoneyThread(account, 1)
threads.append(t)
t.start()
# 等所有存款的线程都执行完毕
for t in threads:
t.join()
print('账户余额为: ¥%d元' % account.balance)
if __name__ == '__main__':
main()
我们可以通过“锁”来保护“临界资源”,只有获得“锁”的线程才能访问“临界资源”,
而其他没有得到“锁”的线程只能被阻塞起来,直到获得“锁”的线程释放了“锁”,
其他线程才有机会获得“锁”,进而访问被保护的“临界资源”
from time import sleep
from threading import Thread, Lock
class Account(object):
def __init__(self):
self._balance = 0
self._lock = Lock()
def deposit(self, money):
# 先获取锁才能执行后续的代码
self._lock.acquire()
try:
new_balance = self._balance + money
sleep(0.01)
self._balance = new_balance
finally:
# 在finally中执行释放锁的操作保证正常异常锁都能释放
self._lock.release()
@property
def balance(self):
return self._balance
class AddMoneyThread(Thread):
def __init__(self, account, money):
super().__init__()
self._account = account
self._money = money
def run(self):
self._account.deposit(self._money)
def main():
account = Account()
threads = []
for _ in range(100):
t = AddMoneyThread(account, 1)
threads.append(t)
t.start()
for t in threads:
t.join()
print('账户余额为: ¥%d元' % account.balance)
if __name__ == '__main__':
main()
"""
Day13_Process_Thread
最新推荐文章于 2024-09-18 10:49:43 发布
本文深入探讨了Python中的多线程技术,包括线程的创建、同步与通信,以及在实际项目中如何利用线程提升程序执行效率。通过实例解析,详细阐述了线程池的使用,并对比了线程与进程的区别,帮助读者掌握多线程编程的核心概念。
摘要由CSDN通过智能技术生成