Python并发编程之进程同步

Posted Micheal_L

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python并发编程之进程同步相关的知识,希望对你有一定的参考价值。


"""
问题:当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱的问题
"""
'''
进程同步
'''
#多进程抢占输出资源
import os
import time
import random
from multiprocessing import Process

def work(n):
    print(f'{n}: {os.getpid()} is running')
    # time.sleep(random.random())
    time.sleep(2)
    print(f"{n}: {os.getpid()} is done")
if __name__ == '__main__':
 for i in range(3):
     p = Process(target= work, args=(i, ))
     p.start()

#使用锁维护执行顺序

#由并发变成了串行,牺牲了运行效率,但避免了竞争
import os,time,random
from multiprocessing import Process,Lock

def work(lock, n):
    lock.acquire()
    print(f'{n}: {os.getpid()} is running')
    time.sleep(random.randint(1, 3))
    print(f'{n}: {os.getpid()} is done')
    lock.release()

if __name__ == '__main__':
    lock = Lock()
    for i in range(3):
        p = Process(target=work, args=(lock, i))
        p.start()
'''加锁可以实现顺序的执行,但是程序又重新变成串行了,
浪费时间但是保证了数据安全
'''
#文件db的内容为:{"count": 1}
#注意一定要用双引号,不然json无法识别
#并发运行,效率高,但竞争写同一文件,数据写入错乱

from multiprocessing import Process,Lock
import time, json, random

def search():#查询剩余票数
    dic = json.load(open('db')) #从文件中把数据读出来
    # 下面两句和上面一句的功能一样
    # data = open('db')
    # dic = json.load(data)
    print(f'剩余票数{dic["count"]}')#打印
def get():#买票
    dic = json.load(open('db')) #打开文件
    time.sleep(0.1) #模拟读数据的网络延迟
    if dic['count'] > 0:
        dic['count'] -= 1
        time.sleep(0.2) #模拟写数据的网络延迟
        json.dump(dic, open('db', 'w'))
        # 下面两句和上面一句会得到相同的效果
        # data = open('db', 'w')
        # json.dump(dic, data)
        print('购票成功')
def task():
    search()
    get()

if __name__ == '__main__':
    for i in range(100): # 模拟并发100个客户端抢票
        p = Process(target=task)
        p.start()


#用锁来保证数据安全
from multiprocessing import Process,Lock
import time, json, random

def search():#查询剩余票数
    dic = json.load(open('db')) #从文件中把数据读出来
    # 下面两句和上面一句的功能一样
    # data = open('db')
    # dic = json.load(data)
    print(f'剩余票数{dic["count"]}')#打印
def get():#买票
    dic = json.load(open('db')) #打开文件
    time.sleep(random.random()) #模拟读数据的网络延迟
    if dic['count'] > 0:
        dic['count'] -= 1
        time.sleep(random.random()) #模拟写数据的网络延迟
        json.dump(dic, open('db', 'w'))
        # 下面两句和上面一句会得到相同的效果
        # data = open('db', 'w')
        # json.dump(dic, data)
        print('购票成功')
def task(lock):
    search()
    lock.acquire()
    get()
    lock.release()

if __name__ == '__main__':
    lock = Lock()
    for i in range(30): # 模拟并发100个客户端抢票
        p = Process(target=task, args=(lock, ))
        p.start()
"""
加锁可以保证多个进程修改同一块数据时,同一时间只
能有一个任务可以修改即串行的修改,速度慢了,但是数
据变安全了。

文件共享数据实现进程间通信,问题有:
1.效率低(共享数据基于文件,而文件是在硬盘上的数据) 
2.需要自己加锁处理

我们需要:
1.效率高,(多个进程共享一块内存的数据)
2.帮我们处理好锁问题,这就是multiprocessing模块提供
的基于消息的IPC通信机制:队列和管道

注意:
队列和管道都是将数据存放于内存中,队列又是基于(管道+锁)
实现的,可以让我们从复杂的锁问题中解脱出来,我们应该尽量
避免使用共享数据,尽可能使用消息传递和队列,避免处理复
杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。

"""

以上是关于Python并发编程之进程同步的主要内容,如果未能解决你的问题,请参考以下文章

Python并发编程之同步异步and阻塞非阻塞

Python并发编程之进程

python 之 并发编程(进程池与线程池同步异步阻塞非阻塞线程queue)

python并发编程之多进程:互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

python并发编程之IO模型,

python并发编程之IO模型