zoukankan      html  css  js  c++  java
  • 进程通信与线程

    一 、进程间通信(IPC机制)

    队列:先进先出

    堆栈:先进后出

    利用队列实现进程间通信

    from multiprocessing import Queue


    q = Queue(5)      # 产生一个最多能够存放五个数据的队列

    # q.put(1)      # 往队列中存放数据,如果存放的数据个数大于队列最大存储个数,程序会阻塞
    # q.put(2)
    # q.put(3)
    # print(q.full())
    q.put(4)
    # q.put(5)
    # print(q.full())
    # for i in range(6):
    # q.put(i)

    # 存取数据
    for i in range(5):
    q.put(i)      # for循环往队列里面存放数据
    print(q.get())      # 取数据,get一次就取一个
    print(q.get())
    print(q.get())
    q.get_nowait()     # 在队列有数据的情况下,跟get取值一样,当队列没有数据的情况下,取值直接报错  

                                # q.get_nowait():同q.get(False)

    print(q.empty())     # 判断队列是否为空,需要注意的是,在并发的情况下,这个方法判断不准确!
    print(q.get())
    print(q.get())
    print(q.empty())
    # q.get_nowait()
    # print(q.get())     # 如果队列为空,get会在原地等待队列中有数据过来

    二 、基于队列实现进程间通信 

    from multiprocessing import Queue,Process


    def producer(q):
    q.put('hello baby!')


    def consumer(q):
    print(q.get())

    if __name__ == '__main__':
    q = Queue()       # 生成一个队列对象
    p1 = Process(target=producer,args=(q,))
    c1 = Process(target=consumer,args=(q,))
    p1.start()
    c1.start()

    三 、 生产者消费者模型(重点)

    """
    生产者:做包子的 生产数据的
    消费者:买包子的 处理数据的

    解决供需不平衡的问题
    定义一个队列,用来存放固定数量的数据
    解决一个生产者和消费者不需直接打交道,两者都通过队列实现数据传输

    Queue:管道+锁
    """


    from multiprocessing import Queue,Process,JoinableQueue
    import time
    import random


    def producer(name,food,q):
    for i in range(5):
    data = '%s生产了%s%s'%(name,food,i)
    time.sleep(random.randint(1,3))
    print(data)
    q.put(data)       # 将生产的数据放入队列中


    def consumer(name,q):
    while True:
    data = q.get()
    if data is None:break
    time.sleep(random.randint(1, 3))
    print('%s吃了%s'%(name,data))
    q.task_done()       # 告诉你的队列,你已经将数据取出并且处理完毕


    if __name__ == '__main__':
    q = JoinableQueue()      # 生成一个队列对象
    p1 = Process(target=producer,args=('大厨egon','包子',q))
    p2 = Process(target=producer,args=('靓仔tank','生蚝',q))
    c1 = Process(target=consumer,args=('吃货owen',q))
    c2 = Process(target=consumer,args=('坑货kevin',q))
    p1.start()
    p2.start()
    c1.daemon = True
    c2.daemon = True
    c1.start()
    c2.start()
    # 等待生产者生产完所有的数据
    p1.join()
    p2.join()
    # 在生产者生产完数据之后,往队列里面放一个提示性的消息,告诉消费者已经没有数据,你走吧,不要等了
    # q.put(None)
    # q.put(None)
    q.join()      # 等待队列中数据全部取出
    print('主')

    线程

    1 、什么是线程?

        进程:资源单位

        线程:执行单位

        注意:每一个进程中都会自带一个线程

    2 、为什么要有线程

        开一个进程:

          申请一个内存空间   耗时

          将代码拷贝到申请的内存空间中  耗时

        开线程:

          不需要申请内存空间

        开线程的开销远远小于开进程的开销!

    3 、如何使用线程:几乎和进程一毛一样

    一 、开启线程的两种方式

      

      方式一: 

     from threading import Thread
     import time

     def task(name):
     print('%s is running'%name)
     time.sleep(1)
     print('%s is over'%name)

     if __name__ == '__main__':
     t = Thread(target=task,args=('egon',))
     t.start()        # 开启线程的速度非常快,几乎代码执行完线程就已经开启
     print('主')

      方式二:

    from threading import Thread
    import time

    class MyThread(Thread):
    def __init__(self,name):
    super().__init__()
    self.name = name
    def run(self):
    print('%s is running' % self.name)
    time.sleep(1)
    print('%s is over'%self.name)

    if __name__ == '__main__':
    t = MyThread('jason')
    t.start()
    print('主')

    二 、线程之间数据共享

    from threading import Thread

    x = 100

    def task():
    global x
    x = 666

    t = Thread(target=task)
    t.start()
    t.join()
    print(x)

    -->>   1

    三 、 线程互斥锁

    from threading import Thread,Lock
    import time

    mutex = Lock()
    n = 100

    def task():
    global n
    mutex.acquire()        #加锁
    tmp = n
    time.sleep(0.1)
    n = tmp -1
    mutex.release()            #释放


    t_list = []
    for i in range(100):
    t = Thread(target=task)
    t.start()
    t_list.append(t)

    for t in t_list:
    t.join()

    print(n)

    四 、 线程对象的其他属性和方法

    from threading import Thread,active_count,current_thread
    import os
    import time


    def task(name):
    # print('%s is running'%name,os.getpid())
    print('%s is running'%name,current_thread().name,current_thread().getName())
    time.sleep(1)
    print('%s is over'%name)

    def info(name):
    print('%s is running' % name, current_thread().name, current_thread().getName())
    time.sleep(1)
    print('%s is over' % name)

    t = Thread(target=task,args=('关磊',))
    t1 = Thread(target=info,args=('关超',))
    t.start()
    t1.start()
    t.join()
    print(active_count())       # 当前存活的线程数
    print(os.getpid())
    print(current_thread().name)
    print(current_thread().getName())

    五 、 守护线程

    from threading import Thread
    import time


    def task(name):
    print('%s is running'%name)
    time.sleep(1)
    print('%s is over'%name)

    if __name__ == '__main__':
    t = Thread(target=task,args=('王磊',))
    # t.daemon = True
    t.start()
    print('主')

  • 相关阅读:
    Hammer.js 实现移动端库事件
    使用两个队列模拟一个栈
    选择排序算法
    插入排序算法
    找出一个整形数组中第二大的数字
    双向冒泡排序算法
    求一个整形数组的最大子数组之和
    循环删除数组中元素的问题
    关于如何输出if()..else里的内容的问题
    小米2017秋招真题——电话号码分身问题(Java版)
  • 原文地址:https://www.cnblogs.com/SlookUp/p/10827484.html
Copyright © 2011-2022 走看看