zoukankan      html  css  js  c++  java
  • 2018年5月19日笔记

    • 进程的概念

    进程是程序在计算机上的一次执行活动。

    进程可分为系统进程和用户进程。

    所有正在运行的进程轮流使用CPU,任何一个时间点有且只有一个进程占用CPU。

    • 进程与线程的区别

    进程 > 线程

    多进程使用CPU的多个核,适合运算密集型

    多线程使用CPU的一个核,核心IO密集型

    • python多进程 —— muiltiprocessing模块

    python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了multiprocessing。

    Multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。

    • 创建一个Process实例
    p1 = multiprocessing.Process(target=func, args=(2,))

    target=函数名字

    args=函数所需的参数,以tuple形式传入,必须有逗号,注意单个参数的形式

    multiprocessing的2个常用方法:

    multiprocessing.cpu_count()     # 1. 统计CPU总数
    
    multiprocessing.active_children()       # 2. 获取所有子进程
    • Process实例的常用属性和方法

    常用属性:

    p1 = multiprocessing.Process(target=func, args=(2,))
    p1.name     # 进程名字
    p1.pid      # 进程ID

    常用方法:

    p1 = multiprocessing.Process(target=func, args=(2,))
    p1.is_alive()       # 判断进程是否存活
    p1.run()            # 启动进程(不常用)
    p1.start()          # 启动进程,自动调用run()方法(常用)
    p1.join(timeout=5)  # 等待进程结束或直到超时(5s)
    • 习题1
     1 import multiprocessing
     2 import time
     3 
     4 
     5 def worker(args, interval):
     6     print("start worker {0}".format(args))
     7     time.sleep(interval)
     8     print("end worker {0}".format(args))
     9 
    10 def main():
    11     print("start main")
    12     p1 = multiprocessing.Process(target=worker, args=(1, 1))
    13     p2 = multiprocessing.Process(target=worker, args=(2, 2))
    14     p3 = multiprocessing.Process(target=worker, args=(3, 3))
    15     p1.start()
    16     p2.start()
    17     p3.start()
    18     print("end main")
    19 
    20 if __name__ == '__main__':
    21     main()
    start main
    end main
    start worker 1
    start worker 2
    start worker 3
    end worker 1
    end worker 2
    end worker 3
    • 习题2
     1 import multiprocessing
     2 import time
     3 
     4 def worker(args, interval):
     5     print("start worker {0}".format(args))
     6     time.sleep(interval)
     7     print("end worker {0}".format(args))
     8 
     9 def main():
    10     print("start main")
    11     p1 = multiprocessing.Process(target=worker, args=(1, 1))
    12     p2 = multiprocessing.Process(target=worker, args=(2, 2))
    13     p3 = multiprocessing.Process(target=worker, args=(3, 3))
    14     p1.start()
    15     p1.join(timeout=0.5)
    16     p2.start()
    17     p3.start()
    18     print("the number of CPU is: {0}".format(multiprocessing.cpu_count()))
    19     for p in multiprocessing.active_children():
    20        print("The name of active children is: {0}, pid is: {1} is alive".format(p.name, p.pid))
    21     print("end main")
    22 
    23 if __name__ == '__main__':
    24     main()
    start main
    start worker 1
    the number of CPU is: 4
    The name of active children is: Process-1, pid is: 1348 is alive
    The name of active children is: Process-3, pid is: 1350 is alive
    The name of active children is: Process-2, pid is: 1349 is alive
    end main
    start worker 2
    start worker 3
    end worker 1
    end worker 2
    end worker 3
    • Lock组件

    使用多进程来读写文件时,读和写不能同时进行,为了这种多个进程共享同一资源的场景不出问题,引入了锁机制。

    锁有两种状态:被锁(locked)和没有被锁(unlocked)。拥有acquire()和release()两种方法,并且遵循一下的规则:

    • 如果一个锁的状态是unlocked,调用acquire()方法改变它的状态为locked
    • 如果一个锁的状态是locked,acquire()方法将会阻塞,直到另一个线程调用release()方法释放了锁;
    • 如果一个锁的状态是unlocked调用release()会抛出RuntimeError异常;
    • 如果一个锁的状态是locked,调用release()方法改变它的状态为unlocked。
    • 习题3
     1 import multiprocessing
     2 import time
     3 
     4 def add1(lock, value, number):
     5     with lock:
     6         print("start add1 number= {0}".format(number))
     7         for i in range(1, 5):
     8             number += value
     9             time.sleep(0.3)
    10             print("number = {0}".format(number))
    11 
    12 def add3(lock, value, number):
    13     lock.acquire()
    14     print("start add3 number= {0}".format(number))
    15     try:
    16         for i in range(1, 5):
    17             number += value
    18             time.sleep(0.3)
    19             print("number = {0}".format(number))
    20     except Exception as e:
    21         raise e
    22     finally:
    23         lock.release()
    24         pass
    25 
    26 if __name__ == '__main__':
    27     print("start main")
    28     number = 0
    29     lock = multiprocessing.Lock()
    30     p1 = multiprocessing.Process(target=add1, args=(lock, 1, number))
    31     p3 = multiprocessing.Process(target=add3, args=(lock, 3, number))
    32     p1.start()
    33     p3.start()
    34     print("end main")
    start main
    end main
    start add1 number= 0
    number = 1
    number = 2
    number = 3
    number = 4
    start add3 number= 0
    number = 3
    number = 6
    number = 9
    number = 12
    • 多进程间可共享内存

    multiprocessing模块提供了共享内存的操作。

    一般的变量在进程之间是无法通信的,multiprocessing提供了Value和Array模块,实现了进程间的数据共享。

    Python中还提供了强大的Manager模块专门来做数据共享,其支持的类型非常多,包括Value, Array, list, dict, Queue, Lock等。

    • 习题4
     1 import multiprocessing
     2 from multiprocessing import Value, Array, Manager
     3 import time
     4 
     5 
     6 def add1(value, number):
     7     print("start add1 number= {0}".format(number.value))
     8     for i in range(1, 5):
     9         number.value += value
    10         print("number = {0}".format(number.value))
    11 
    12 def add3(value, number):
    13     print("start add3 number= {0}".format(number.value))
    14     try:
    15         for i in range(1, 5):
    16             number.value += value
    17             print("number = {0}".format(number.value))
    18     except Exception as e:
    19         raise e
    20 
    21 if __name__ == '__main__':
    22     print("start main")
    23     number = Value('d', 0)
    24     p1 = multiprocessing.Process(target=add1, args=(1, number))
    25     p3 = multiprocessing.Process(target=add3, args=(3, number))
    26     p1.start()
    27     p3.start()
    28     print("end main")
    start main
    end main
    start add1 number= 0.0
    number = 1.0
    number = 2.0
    number = 3.0
    number = 4.0
    start add3 number= 4.0
    number = 7.0
    number = 10.0
    number = 13.0
    number = 16.0
  • 相关阅读:
    为什么java使用对象序列化到文件,打开之后是乱码,而且更换编码格式查看也不能正常显示呢
    String类能够导入IDEA,但是里面的构造方法无法使用,一直显示报错
    IDEA不能提示导入java.io.File类,但是自己手写import没问题,最后找到了问题所在
    扑克牌发牌,排序的功能实现
    TFS 生成定义
    Git-tfs工具
    日期和时间
    调用惯例
    优化查找和排序
    使用更好的库
  • 原文地址:https://www.cnblogs.com/karl-python/p/9065123.html
Copyright © 2011-2022 走看看