python 中的进程与线程

  1. 进程池

    # -*- coding:utf-8 -*-
    # V : 3.7.4
    from multiprocessing import Pool
    import time
    
    
    def func(i):
        print(f'任务 {i} 开始时间为:{time.ctime()}')
        time.sleep(10)
        print(f'任务 {i} 结束时间为:{time.ctime()}')
    
    
    if __name__ == '__main__':
        # 创建进程池,默认为 CPU 的核数
        pool = Pool(4)  # 创建 4 个进程
        for i in range(10):
            # print(f'开始执行任务{i}')
            time.sleep(1)
            pool.apply_async(func, (i,))
            # apply_async(self, func, args=(), kwds={})
            # func : 需要执行的函数
            # args :  传入的参数。以元组形式,只有一个参数需要加上逗号
            # kwds :  传入的参数。以字典形式
    
        pool.close()    # 当进程池中不在有任务是关闭进程
        pool.join()     # 等待所有的子进程执行完毕
    
    
    # 各进程之间的变量不共享,因为每个进程都有属于之间的独立空间
    
  2. 队列的常用方法

    # -*- coding:utf-8 -*-
    # V : 3.7.4
    from multiprocessing import Queue
    
    if __name__ == '__main__':
        # 创建队列,默认为无限,
        queue = Queue(4)
    
        # queue.put(obj, block=True, timeout=None)  # 插入元素,设置block为 True,timeout等待时间操作时,当队列满了的时候会报错
        # queue.get(block=True, timeout=None)       # 取出并删除元素,设置block为 True,timeout等待时间操作时,当队列没有时会报错
        # queue.qsize()                             # 查看队列大小
        # queue.full()                              # 判断队列是否也满,返回 True 或者 False
        # queue.empty()                             # 判断队列是否已空,返回 True 或者 False
    
  3. 进程之间的通信

    # -*- coding:utf-8 -*-
    # V : 3.7.4
    
    from multiprocessing import Process, Queue
    import time
    
    def write(q):
        a = [1, 2, 3, 4, 5, 6]
        for i in a:
            print(f'开始写入队列{i}')
            q.put(i)
            time.sleep(1)
    
    
    def read(q):
        for i in range(q.qsize()):
            print(f'开始读取队列的{q.get()}')
            time.sleep(1)
    
    if __name__ == '__main__':
    
        q = Queue()
        p_w = Process(target=write, args=(q,))
        p_r = Process(target=read, args=(q,))
        # 注意写入完在读取。不然会读取不完整
        p_w.start()
        p_w.join()
        p_r.start()
        p_r.join()
    
  4. 进程池之间的通信

    # -*- coding:utf-8 -*-
    # V : 3.7.4
    
    from multiprocessing import Process, Pool, Manager
    import time
    
    def write(q):
        a = [1, 2, 3, 4, 5, 6]
        for i in a:
            print(f'开始写入队列{i}')
            q.put(i)
            time.sleep(1)
    
    
    def read(q):
        for i in range(q.qsize()):
            print(f'开始读取队列的{q.get()}')
            time.sleep(1)
    
    if __name__ == '__main__':
        q = Manager().Queue()       # 进程池使用的是 Manger() 中的 Queue() 方法
        p = Pool(3)                 # 创建三个进程
        p.apply(write, (q,))        # 必须使用 apply 方法,使其阻塞以写入所有的队列
        p.apply(read, (q,))
    
        p.close()
        p.join()
    
  5. thrending 线程

    # -*- coding:utf-8 -*-
    # V : 3.7.4
    
    import threading
    import time
    
    
    def func1(name, wait):
        print(f'线程{name}开始运行')
        time.sleep(wait)
        print(f'线程{name}结束运行')
    
    
    def func2(name, wait):
        print(f'线程{name}开始运行')
        time.sleep(wait)
        print(f'线程{name}结束运行')
    
    
    if __name__ == '__main__':
        print('主程序开始运行')
    
        # 创建线程
        t1 = threading.Thread(target=func1, args=('func1', 2))
        t2 = threading.Thread(target=func2, args=('func2', 5))
    
        # 开始运行
        t1.start()
        t2.start()
    
        # 结束运行
        t1.join()
        t2.join()
    
  6. 线程之间共享全局变量

    # -*- coding:utf-8 -*-
    # V : 3.7.4
    
    import threading
    import sys
    
    num = 13
    
    def func1():
        global num
        num += 5
        print(f'函数{sys._getframe().f_code.co_name}中当前的 num为 {num}')
    
    
    def func2():
        global num
        print(f'函数{sys._getframe().f_code.co_name}中当前的 num为 {num}')
    
    
    if __name__ == '__main__':
        t1 = threading.Thread(target=func1, args=())
        t2 = threading.Thread(target=func2, args=())
    
        # 线程属于一个内存空间。同时执行会出现抢占 CPU 的情况,会导致数据出现混乱
        t1.start()
        t1.join()
    
        t2.start()
        t2.join()
    
  7. 线程之间应该有一把锁

    # -*- coding:utf-8 -*-
    # V : 3.7.4
    
    import threading
    import sys
    
    num = 0
    
    look = threading.Lock()     # 创建一把锁
    
    def func1():
        global num
    
        for i in range(119999):
            look.acquire()  # 上锁
            num += 1
            look.release()       # 解锁
        print(f'函数{sys._getframe().f_code.co_name}中当前的 num为 {num}')
    
    
    def func2():
        global num
    
        for i in range(119999):
            look.acquire()  # 上锁
            num += 1
            look.release()       # 解锁
        print(f'函数{sys._getframe().f_code.co_name}中当前的 num为 {num}')
    
    
    if __name__ == '__main__':
        t1 = threading.Thread(target=func1, args=())
        t2 = threading.Thread(target=func2, args=())
    
        # 由于线程之间加了锁,所以不用担心数据混乱
        # 锁应该加在 数值 改变的地方
        t1.start()
        t2.start()
    
        t1.join()
        t2.join()
    
  8. 线程间的同步锁

    # -*- coding:utf-8 -*-
    # V : 3.7.4
    from threading import Thread, Lock
    import time
    
    # 创建三把锁
    lock1 = Lock()
    lock2 = Lock()
    lock3 = Lock()
    
    #  为 其中的两把锁加锁
    lock2.acquire()
    lock3.acquire()
    
    class test1(Thread):
        def run(self) -> None:
            while 1:
                if lock1.acquire():
                    print('lock1  加锁,解锁 lock2')
                    time.sleep(1)
                    lock2.release()
    
    class test2(Thread):
        def run(self) -> None:
            while 1:
                if lock2.acquire():
                    print('lock2  加锁,解锁 lock3')
                    time.sleep(1)
                    lock3.release()
    
    class test3(Thread):
        def run(self) -> None:
            while 1:
                if lock3.acquire():
                    print('lock3  加锁,解锁 lock1,开始下一个循环')
                    time.sleep(1)
                    lock1.release()
    
    
    if __name__ == '__main__':
        t1 = test1()
        t2 = test2()
        t3 = test3()
    
        # 由于加锁了,数据不会混乱。
        t1.start()
        t2.start()
        t3.start()
    
        t1.join()
        t2.join()
        t3.join()
    
  9. 生产者消费者模式

    # -*- coding:utf-8 -*-
    # V : 3.7.4
    
    from threading import Thread
    from queue import Queue
    import time
    
    class Producer(Thread):
        def run(self) -> None:
            global q
            while 1:
                if q.qsize() < 100:
                    for i in range(50):
                        msg = f'生产第 {i} 个产品'
                        q.put(msg)
                        print(msg)
                    time.sleep(1)
    
    class Consumer(Thread):
        def run(self) -> None:
            global q
            while 1:
                if q.qsize() > 30:
                    for i in range(20):
                        msg = f'消费第 {i} 个产品'
                        q.get()
    
                        print(msg)
                    time.sleep(1)
    
    
    if __name__ == '__main__':
        q = Queue()
        t1 = Producer()
        t2 = Consumer()
    
        t1.start()
        time.sleep(2)
        t2.start()
    
posted @ 2020-05-29 23:11  _懒  阅读(83)  评论(0)    收藏  举报