进程、互斥锁

代码创建进程

'''
创建进程的方式:
	1.鼠标点击桌面一个应用图标
	2.代码创建
创建进程的本质:在内存中申请一块内存空间用于运行相应的程序代码
'''
# 第一种创建进程的方式
from multiprocessing import Process
import time

def index():
    print('这里是index')



if __name__ == '__main__':
    print('start')
    p = Process(target=index)
    p.start()
    print('wait')
    time.sleep(1)
    print('end')
    
>>>start
>>>wait
>>>这里是index
>>>end
'''
强调:不同的操作系统创建进程的要求不一样
	在windows中创建进程是以导入模块的方式进行 所以创建进程的代码必须写在__main__子代码中,否则会直接报错 因为在无限制创建进程
	在linux和mac中创建进程是直接拷贝一份源代码然后执行,不需要写在__main__子代码中
'''
# 创建进程的第二种方式
from multiprocessing import Process
import time
class MyProcess(Process):
    def __init__(self, username):
        self.username = username
        super().__init__()
    def run(self):
        print('你好啊 小姐姐',self.username)
        time.sleep(3)
        print('get out!!!',self.username)
if __name__ == '__main__':
    p = MyProcess('jason')
    p.start()
    print('主进程')
>>>主进程
>>>你好啊 小姐姐 jason
>>>get out!!! jason

进程实现并发

'''
将于客户端通信的代码封装成一个函数,之后每来一个客户端就创建一个进程专门做交互
'''
import socket
from multiprocessing import Process
def get_server():
    server = socket.socket()
    server.bind(('127.0.0.1',8888))
    server.listen(5)
    return server

def msg_rcv(sock):
    msg = sock.recv(1024)
    print(msg.decode('utf8'))
    sock.send(b'hello')

if __name__ == '__main__':
    server = get_server()
    while True:
        sock,addr = server.accept()
        p = Process(target=msg_rcv,args=(sock,))
        p.start()

               
#客户端
import socket

while True:
    client = socket.socket()
    client.connect(('127.0.0.1',8888))
    client.send(b'jason')
    msg = client.recv(1024)
    print(msg.decode('utf8'))

join方法

# 让之进程代码等待子进程代码运行完毕在执行
1.join方法的简单使用
2.如何真正理解等待的过程

from multiprocessing import Process
import time


def task(name, n):
    print(f'{name} is running')
    time.sleep(n)
    print(f'{name} is over')


if __name__ == '__main__':
    p1 = Process(target=task, args=('jason', 1))
    p2 = Process(target=task, args=('tony', 2))
    p3 = Process(target=task, args=('kevin', 3))
    start_time = time.time()
    p1.start()
    p2.start()
    p3.start()
    p1.join()
    p2.join()
    p3.join()
    end_time = time.time() - start_time
    print('主进程', f'总耗时:{end_time}')  # 主进程总耗时3.273492894989678
    # 如果是一个start一个join交替执行那么总耗时就是各个任务耗时总和
'''
需求:p.start()之后的代码等待子进程全部运行结束之后在打印
1.错误做法:
	直接sleep
	因为不知道子进程运行的时间
2.join方法
'''

进程间数据默认隔离

# 内存可以看成 是由多个小隔间组成彼此不干扰
from multiprocessing import Process

money = 999


def task():
    global money  # 局部修改全局不可变类型
    money = 666


if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    p.join()  # 确保子进程代码运行结束再打印money
    print(money)

'''默认隔离 但是可以通过一些技术打破'''

进程对象属性和方法

'''
进程号查看:
	windows:	tasklist的结果集中能够查看
    mac: 		ps -ef
'''
1.进程号代码查看方法

# 使用current_process函数查看
    from multiprocessing import Process,current_process
    curren_process().pid
    '''获取进程号的用处之一就是可以通过代码的方式管理进程'''在windows中可以通过 taskkill关键字杀死进程
    
# 使用os模块
os.getpid()  # 获取当前进程的进程号
os.getppid()  # 获取当前进程的父进程号

2.杀死子进程
terminate()
3.判断子进程是否存活
is_alive()

僵尸进程于孤儿进程

僵尸进程:
	# 为什么主进程默认需要等待子进程结束才会结束
    所有的子进程在运行结束之后都会变成僵尸进程(死了但没有死透)
    还保留这pid和一些运行过程中的记录便于主进程查看(短时间保存),这些信息会被主进程回收(彻底死亡)
    
孤儿进程:
	# 子进程存活父进程意外死亡
    子进程会被操作系统自动接管

守护进程

'''
守护 即死活全部参考守护对象
	对象死亡自身则立即死亡
'''
from multiprocessing import Process
import time
def a():
    print('live')
    time.sleep(0.5)
    print("died")

if __name__ == '__main__':
    p = Process(target=a)
    p.daemon = True
    p.start()
    time.sleep(0.5)
    print('死了')

>>>live
>>>死了

互斥锁

'''
情景:
节假日抢票,手机显示还有票,但是点击购买的时候却提示已经没有票了,之后刷新查询确实是没票了
原因:上午10:00打开软件查询票数 接受到的数据是系统发过来的10:00的数据
只要不进行刷新,那么页面显示的永远是10:00的信息
'''
代码模拟抢票
import json
from multiprocessing import Process
import time


# 查询票数
def view_ticket_num():
    with open('data.json', 'r', encoding='utf8') as f:
        dic = json.load(f)
        print(f'当前票数:{dic["ticket_num"]}')
    return dic


# 买票
def buy_ticket(i):
    # 查票
    dic = view_ticket_num()
    num = dic['ticket_num']
    time.sleep(1)
    if num > 0:
        # 买票
        dic['ticket_num'] -= 1
        with open('data.json', 'w', encoding='utf8') as f:
            json.dump(dic, f)
        print(f'用户{i},买票成功')


if __name__ == '__main__':
    for i in range(1, 10):
        p = Process(target=buy_ticket, args=(i,))
        p.start()
        
'''
当多个进程操作同一份数据的时候会造成数据的错乱
	这个时候就需要加锁处理(互斥锁)
		即将并发并称串行 牺牲了效率但是保证了数据的安全

互斥锁不能随意使用 容易造成死锁现象
互斥锁只能在处理数据的部分枷锁不能什么地方都加 严重影响程序的效率
'''
查票可以一次性给多人看 但是买票环节必须排队>>>互斥锁

from multiprocessing import Process, Lock
mutex = Lock()
mutex.acquire() # 抢锁
mutex .release()  # 放锁
'''
锁相关的知识
	行锁:只针对行数据加锁 同一时间只能有一个人操作
	表锁:只针对表数据进行加锁 同一时间只能一个人操作
'''
posted @   名字只需六字  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示