进程与线程的简介:
进程 - 操作系统分配内存的基本单位,进程之间的内存相互独立的,ipc机制可以相互访问,套接字(sokect)
线程 - 一个进程可以划分为多个线程,线程是进程的执行单元也是操作系统分配cpu的基本单元
为什么要使用多线程:得到更多的cpu的调用
1 如果一个任务执行时间很长 我们就可以将一个任务分为多个线程 改善程序的执行效率 缩短执行时间
2 改善用户体验
进程的定义与使用
关键字Process
例如:
import time
from multiprocessing import Process
import os
# process
# thread
def output():
print(os.getpid()) # 端口号
while True:
print('ljl', end='', flush=True)
time.sleep(1)
def main():
print(os.getpid())
Process(target=output).start() # 子进程
while True:
print('zy', end='', flush=True)
time.sleep(1)
if __name__ == '__main__':
main()
使用进程模拟下载文件:
import time
import random
from threading import Thread
from multiprocessing import Process
# 如果多个任务之间没有任何的关联(独立子任务)而希望利用CPU的多核特性
# 那么我们推荐使用多进程
# Information Technology
# 摩尔定律 -
# 安迪比尔定律 -
# 反摩尔定律 -
def download(filename):
print('开始下载%s。。。' % filename)
delay = random.randint(5, 15)
time.sleep(delay)
print('%s下载完成,用时%d秒.' % (filename, delay))
def main():
start = time.time()
p1 = Process(target=download, args=('python从入门到住院.pdf', ))
p1.start()
p2 = Process(target=download, args=('pekin hot.avi.pdf',))
p2.start()
p1.join() # 等待p1进程结束 join()保护进程
p2.join()
end = time.time()
print('总共耗费了%f秒' % (end - start))
if __name__ == '__main__':
main()
线程
守护线程 不值得保留的线程 其它线程如果都执行完毕了那么守护线程自动结束
daemon=True 将线程设置为守护线程
t1 = Thread(target=output, args=('zy', ), daemon=True) # 定义一个名为t1的线程, target 表示的是要执行的动作 方法 函数名
t1.start()
t2 = Thread(target=output, args=('ljl', ), daemon=True) # deamon 守护线程 当主程序结束则结束
t2.start()
使用线程
当然创建线程我们也可以使用函数来创建,例如:
from threading import Thread
# 创建线程的两种方式
# 1. 直接创建Thread对象并通过target参数指定线程启动后要执行的任务
# 2. 继承Thread自定义线程 通过写run方法指定线程启动后执行的任务
class PrintThread(Thread):
def __init__(self, string, count):
super().__init__()
self._string = string
self._count = count
def run(self): # 这里的run方法不能更改函数名
"""需要写的判断条件或者循环条件"""
for _ in range(self._count):
print(self._string, end='', flush=True) # flush是将相应的立即输出
def main():
PrintThread('pin', 5).start()
PrintThread('pon', 5).start()
if __name__ == '__main__':
main()
1.多线程控制小车的移动以及绘制窗口。
from random import randint
from threading import Thread
import pygame
import time
# 2 赛车游戏 5 个线程控制5个车移动
BLACK_COLOR = [0, 0, 0]
GREEN_COLOR = [0, 255, 0]
WHITE_COLOR = [255, 255, 255]
class GameObject(object):
def __init__(self, x, y, size):
self._x = x
self._y = y
self._size = size
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
def draw(self, screen):
pass
class Car(GameObject):
def __init__(self, x, y, size):
super().__init__(x, y, size)
def draw(self, screen):
pygame.draw.rect(screen, GREEN_COLOR, [self._x, self._y, self._size, self._size], 0)
pygame.draw.rect(screen, WHITE_COLOR, [self._x, self._y, self._size, self._size], 1)
def move(self):
if self._x + self._size < 400:
self._x += randint(5, 10)
def main():
class My_thread(Thread):
def run(self):
while True:
screen.fill((255, 255, 255))
pygame.draw.line(screen, BLACK_COLOR, (30, 0), (30, 200), 4)
pygame.draw.line(screen, BLACK_COLOR, (400, 0), (400, 200), 4)
for car in car_list:
car.draw(screen)
pygame.display.flip()
time.sleep(0.1)
for car in car_list:
car.move()
car_list = []
for index in range(5):
car1 = Car(10, 10 + 40 * index, 20)
car_list.append(car1)
pygame.init()
screen = pygame.display.set_mode([500, 200])
pygame.display.set_caption('小车车')
my_thread = My_thread(daemon=True)
my_thread.start()
runing = True
while runing:
for event in pygame.event.get():
if event.type == pygame.QUIT:
runing = False
# screen.fill([200, 200, 200])
pygame.display.flip()
pygame.quit()
if __name__ == '__main__':
main()
2.多个人给一个银行账户转钱
import time
from threading import Thread, Lock
class Account(object):
def __init__(self):
self._balance = 0
self._lock = Lock()
@property
def balance(self):
return self._balance
def deposit(self, money):
# 当多个线程同时访问一个资源的时候 就有可能因为竞争资源导致资源的状态错误
# 被多个线程访问的资源我们通常称之为临界资源 对临界资源的访问需要加上保护
if money > 0:
# 加锁 别乱加锁
self._lock.acquire()
try:
new_balance = self._balance + money
time.sleep(0.01)
self._balance = new_balance
finally:
# 解锁
self._lock.release()
class AddMoneyThread(Thread):
def __init__(self, user):
super().__init__()
self._user = user
def run(self):
self._user.deposit(1)
def main():
account = Account()
tlist = [] # 等下保存所要执行的线程
# 创建多个线程可以使用循环来解决
for _ in range(100):
t = AddMoneyThread(account)
tlist.append(t)
t.start()
for t in tlist:
# 等所有线程结束后才结束该主线程
t.join()
print('账户余额: %d' % account.balance)
if __name__ == '__main__':
main()