一、进程的概念
进程的概念起源于操作系统的
一个完整的计算机系统应该包含三层: 硬件/操作系统/应用程序
硬件:用来运行软件的 硬件之外的都是软件
应用程序:指的是完成某项任务开发运行在操作系统之上的
操作系统位于硬件和应用程序之间 本质上也是一个软件 为应用程序员提供了系统调用接口,有了这些接口后 程序员就只需要考虑如何实现软件不需要再考虑硬件的细节
你打开QQ 你是基于操作系统给你提供点击方式 给操作系统发送请求
操作系统之上管理多个应用程序 多个应用程序要执行 都要CPU 硬件是操作系统管的
正在进行的程序叫做进程 程序不运行的话就是文件 一堆代码而已
pid 进程id 每个运行的程序都有一个pid 在整个操作系统当中是唯一的对某个进程的标识
进程是操作系统当中最小的资源分配单位.
多个进程要执行都要给操作系统发送请求说他们要CPU
操作系统会根据自己的调度算法 去选择把硬件资源给那个进程使用
# 1. 先来先服务
# 2. 时间片轮转
# 多道程序设计 recv(等 阻塞)
# 有多个程序在操作系统中执行当一个进程遇到IO操作的时候就会把CPU让出来给其他程序使用
# 3. 时间片轮转
# 就是把cpu的工作时间分成时间片(0.0秒)
# 4. 多级反馈队列算法
1.2 进程的创建
- 用户交互请求, 而创建一个进程
- 一个进程在运行的过程当中 开子进程pycharm(运行起来之后也是一个进程 py程序开启一个进程)
- 我们现在学了进程 在一个程序在运行的过程当中 开启一个子进程来执行程序
二、multiprocessing模块
from multiprocessing import Process
import os
import time
def func():
print('子进程执行')
# os.getpid() 当前进程id
# os.getppid() 当前进程的父id
print('子进程', os.getpid(), os.getppid())
time.sleep(10)
if __name__ == '__main__': # Windows系统上要加上这一行代码
print('主进程', os.getpid(), os.getppid())
p = Process(target=func) # 创建一个进程对象
p.start() # 给操作系统说 启动一个进程
print('主进程执行完成了')
2.1 传参
from multiprocessing import Process
import os
import time
def func(a):
print('子进程执行')
# os.getpid() 当前进程id
# os.getppid() 当前进程的父id
print('子进程', os.getpid(), os.getppid())
time.sleep(10)
if __name__ == '__main__': # Windows系统上要加上这一行代码
print('主进程', os.getpid(), os.getppid())
# args参数需要的是一个元祖 元祖 元祖
p = Process(target=func, args=(1,)) # 创建一个进程对象
p.start() # 给操作系统说 启动一个进程
print('主进程执行完成了')
2.2 进程之间的数据是隔离的
from multiprocessing import Process
# 你们要抓的是周树人 和我鲁迅有什么关系
n = 100
def func():
global n
n = 0
print('子进程里面的n的值', n)
if __name__ == '__main__':
p = Process(target=func)
p.start()
print('主进程里面的n', n)
(主进程里面的n 100)
2.3 启动多个进程
from multiprocessing import Process
n = 100
def func():
global n
n = 0
print('子进程里面的n的值', n)
if __name__ == '__main__':
for i in range(10):
p = Process(target=func)
p.start()
print('主进程里面的n', n)
(主进程里面的n 100)
- 父进程和子进程的启动是异步的
- 同步: 两件事情 一件事情做完了再去做另外一个件事情
- 异步: 两件事情一起做
- 父进程只负责通知操作系统启动子进程 接下来的工作是由操作系统接手 父进程继续执行
三、基于多进程实现套接字
import socket
from multiprocessing import Process
def talk(conn):
while True:
try:
data = conn.recv(1024)
if not data:
break
conn.send(data.upper())
except ConnectionResetError:
break
conn.close()
def server(ip, port):
server = socket.socket()
server.bind((ip, port))
server.listen(5)
while True:
conn, addr = server.accept()
p = Process(target=talk, args=(conn,))
p.start()
if __name__ == '__main__':
server('127.0.0.1', 8080)
from socket import *
client = socket()
client.connect(('127.0.0.1', 8080))
while True:
msg = input('>>>>').strip()
if not msg:
continue
client.send(msg.encode('utf-8'))
data = client.recv(1024)
print(data.decode('utf-8'))
四、join方法
from multiprocessing import Process
import time
def func(index):
time.sleep(3)
print(f"第{index}邮件发送完毕")
if __name__ == '__main__':
p_list = []
for i in range(10):
p = Process(target=func, args=(i, ))
p.start()
p_list.append(p)
for p in p_list:
p.join()
print('发送完毕') #
# p = Process(target=func, args=(10,))
# p.start()
# p.join() # 主进程在这里阻塞了 一直等 等p子进程执行完毕后结束阻塞
# print('发送完毕')
五、开启子进程的第二种方法
from multiprocessing import Process
import time
import random
class Foo(Process):
def __init__(self, name):
super().__init__()
self.name = name
def run(self): # run是一个固定写法 start的时候 自动调用run方法
print('%s piaoing' % self.name)
time.sleep(random.randrange(1, 5))
print('%s piao end' % self.name)
if __name__ == '__main__':
f1 = Foo('铁蛋儿')
f1.start()
f1.join()
print('被抓了')
六、互斥锁
进程之间数据是不共享的,是共享同一套文件系统 所以我们可以访问同一个文件
共享带来的问题就是竞争 竞争带来的问题就是错乱
import json
import time
from multiprocessing import Process, Lock
def search(name):
dic = json.load(open('db.txt'))
time.sleep(1)
print(f'{name}查到余票数{dic["count"]}')
def get(name):
dic = json.load(open('db.txt'))
time.sleep(1)
if dic['count'] > 0:
dic['count'] -= 1
time.sleep(1)
json.dump(dic, open('db.txt', 'w'))
print(f'{name} 购票成功')
else:
print(f'嘿嘿嘿 没得票了 {name} 没有买到票')
def task(name, lock):
search(name)
lock.acquire() # 加锁
get(name)
lock.release() # 释放锁
if __name__ == '__main__':
lock = Lock()
for i in range(10):
name = f'<用户{i}>'
p = Process(target=task, args=(name, lock))
p.start()
升学历
k):
search(name)
lock.acquire() # 加锁
get(name)
lock.release() # 释放锁
if name == ‘main’:
lock = Lock()
for i in range(10):
name = f’<用户{i}>’
p = Process(target=task, args=(name, lock))
p.start()
升学历