并发编程

  并发编程,并发就是从主观上看起来运行多个进程,是在用单核CUP经行处理是使用。并行与之相比,就是客观在同一时间段,处理不同程序。一个CPU只能在一个时间点做一件事情,但是多核计算机可以完成并行。并发编程与计算机硬件的特性有很大关系。

  计算机的发展史,从早期的使用穿孔卡片,到后来的磁带,待现在的磁盘以及读取速度更快的固态硬盘。这些存储设备的一代代更新就是解决CPU利用率,用更快的存储设备与CPU一起工作。存储设备设备的更新迭代,但是做数据处理CUP,如果被占用就不能处理其他数据了。最初单道运行在计算机读取数据和打印数据时,计算机CPU仍处在闲置状态。在一个事件与一个时间之间读入和输出时CPU仍处在闲置状态。

  

  多道技术的应用优化了单道技术的不足。当处理事件A时,让磁盘读取时间B的程序,等待事件A在CPU中运行结束,运行事件B的程序。切换保存状态技术在其中得以运用,使计算机在时间上的复用和空间上的复用的方面都得到了提升。切换保存状态的特点是:当一个程序遇到I/O操作时,操作系统剥夺该程序的运行权限。当一个程序长时间占用CPU,操作系统也会剥夺该程序的运行权限,并且保存运行的状态。操作系统剥夺完程序运行权限后有进程调度。进程调度有四种方式,1,先来先运行方式。2,短作业优先调度方式。3,时间片转换方式。4,多级反馈队列。

  并发就是基于操作系统进程调度的属性,在运行多个程序时主观上看起来就是在同时运行,实际上是计算机的进程调度做到这种效果。

  计算机的进程。进程就是正在运行的程序。进程有三种状态,就绪态,运行态和阻塞态。将要运行进程可以成称之为就绪态,运行进程称之为运行态,当有事件请求,遇到I/O操作时就是处在阻塞态。

  同步与异步:表示的是任务的提交方式。在进程的同步是当程序运行时,任务被提交后等待任务结果出来。而进程的异步是当程序运行时,可以去做其他事情。

  阻塞与非阻塞态:阻塞就是进程运行的阻塞态,而非阻塞态就是。

计算机可以同时启动多个进程,在python中也可以,启动多个进程的方式有两种,都是利用类的来创建。第一种是python中使用内置的类,第二种,自定义类。

from multiprocessing import Process

def task():
    print('子进程')
if __name__ == '__main__':
    p = Process(target=task,)
    p.start()   # 告诉操作系统创建子进程的内存空间,
    print('主进程')
结果:
主进程
子进程

  子进程的创建利用multiprocessing模块中的Process类。在创建子进程的过程:首先是在内存中开辟一块新的子进程的内存空间,将产生的代码copy进去。进程的特点是:每个进程都是一个独立的内存空间,且子进程的创建是随机,子进程的创建时与操作系统有关。使用‘if __name__ == '__main__'’,在内存空间类开辟一块子进程空间时,copy的代码会运行一遍,防止无限制创建进程。

# 子进程创建第二种方式
from multiprocessing import Process

class MyProcess(Process):
    def __init__(self):
        super().__init__()

    def run(self):
        print('子进程')

if __name__ == '__main__':
    p = MyProcess()
    p.start()
    print('主进程')

  在进程创建时,如果需要子进程运行完毕后再运行主进程需要join()方法。

# jion()方法
from multiprocessing import Process

class MyProcess(Process):
    def __init__(self):
        super().__init__()

    def run(self):
        print('子进程')

if __name__ == '__main__':
    p = MyProcess()
    p.start()
    p.join()    # jion方法 等待子进程结束后运行下一步程序
    print('主进程')

僵尸进程与孤儿进程

  僵尸进程:就是之一些进程结束后占用的资源(PID等)没有被回收。自由使用join方法和父进程正常死亡后,才会回收子进程占用资源。

  孤儿进程:父进程非正常结束,子进程资源没有回收。Windows系统与Linux系统都有‘儿童福利院’,可以回收这些进行资源。

守护进程:

  当一个进程结束,守护它的进程也结束。

# 守护进程
from multiprocessing import Process

class MyProcess(Process):
    def __init__(self):
        super().__init__()

    def run(self):
        print('子进程')

if __name__ == '__main__':
    p = MyProcess()
    p.daemon = True   # 设置子进程为守护进程,主进程结束,子进程也立即结束
    p.start()
    print('主进程')

互斥锁

  模拟设置一个抢票情景。当有五个人抢票时,同一时间五个人都可以查到票,但是买票是只允许一个人买票,下一个人在买。否则存票的数据库信息错乱。

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

def show_ticket(i):   # 查票
    with open('a', 'r', encoding='utf-8') as f:
        json_d = f.read()
        ticket = json.loads(json_d)

        f.flush()
    print(f'用户{i}正在查票,剩余票数:{ticket.get("ticket")}')

def buy_ticket(i):  # 买票
    with open('a', 'r', encoding='utf-8') as f:
        json_d = f.read()
        ticket = json.loads(json_d)
    time.sleep(random.randint(1,5))   # 模拟网络延迟
    if ticket.get('ticket') > 0:
        ticket['ticket'] -= 1
        with open('a', 'w', encoding='utf-8') as f:
            json.dump(ticket, f)
            f.flush()
        print(f'用户{i}抢票成功')

    else:
        print(f'用户{i}抢票失败')

def task(lock,i):
    show_ticket(i)
    lock.acquire()  # 抢锁
    buy_ticket(i)
    lock.release()  # 放锁

if __name__ == '__main__':

    key = Lock()
    for i in range(1,6):
        p = Process(target=task, args=(key,i))  # 开启五个进程,经行抢票
        p.start()
    print('主进程结束')
#结果
主进程结束
用户2正在查票,剩余票数:3
用户1正在查票,剩余票数:3
用户3正在查票,剩余票数:3
用户4正在查票,剩余票数:3
用户5正在查票,剩余票数:3
用户2抢票成功
用户1抢票成功
用户3抢票成功
用户4抢票失败
用户5抢票失败
互斥锁 模拟抢票

 进程之间的通信

   进程间的通信又称为IPC机制。利用队列进行数据交互。其中引入队列模块Queue。

'''
进程之间可与互相通信
    子进程间, 主进程与子进程间都可以通信
'''
from multiprocessing import Process, Queue
def producer(q):   # 进程1
    q.put('hello')   # 在队列中添加元素
    q.put('hello, mm')

def consumer(q):
    print(q.get_nowait())  # 获取队列元素,并打印
    
if __name__ == '__main__':
    q = Queue()
    p1 = Process(target=producer,args=(q,) )
    c1 = Process(target=consumer, args=(q,))
    p1.start()
    c1.start()
    print(q.get())  # 主进程获取队列元素,并打印
# 结果
hello
hello, mm

  

原文地址:https://www.cnblogs.com/huaiXin/p/11329260.html