• 3,进程间通信IPC机制,线程,线程通信,互斥锁


    今日内容:
    1,进程间的相互通信
    2,生产者消费者模型
    3,线程
    4,线程间通信
    5,线程互斥锁
    1,进程间相互通信 IPC 机制
    1,基于队列来实现通信Queue,队列就相当于管道+锁
    队列:先进先出
    堆栈:先进后出
    from multiprocessing import Queue
    q = Queue(5) # 括号内可以传参数 表示的是这个队列的最大存储数
    q.put(1)
    q.put(2)
    q.put(3)
    q.put(4)
    q.put(5) 向队列中添加数据
    print(q.full()) 判断队列是否满了,Ture 或 False

    q.get()
    q.get()
    print(q.empty()) 判断队列中的数据是否被取完
    print(q.get()) 从队列中获取数据
    print(q.get())
    print(q.get())

    print(q.get_nowait()) # 取值 没有值不等待,直接报错

    ps:get与put要对应,数量一致,put一次只能从队列中添加一个值,get一次只能拿出一个值
    如果get的数量比put的多,则队列中的值被取完了,此时不会报错,
    就会等待(阻塞),等队列中有值加入时,继续取值操作,同理 put增加值时也是一样的
    即q.put(6) # 当队列满了之后 再放入数据 不会报错 会原地等待 直到队列中有数据被取走(阻塞态)
    当队列中的数据被取完之后 再次获取 程序会阻塞 直到有人往队列中放入值
    补充:
    full(), q.empty(), q.get_nowait() 都不适用于多进程的情况下

    案列: from multiprocessing import Process,Queue
    def scz(q): 要把队列的对象传进来*****
    q.put('hello')
    def xfz(q):
    print(q.get())

    if __name__ == '__main__':
    q = Queue()
    p = Process(target=scz,args=(q,))
    p1 = Process(target=xfz,args=(q,))
    p.start()
    p1.start()
    总结:两个进程之间通信,是通过队列来实现的,把 产生的数据放在队列中,让另一个进程提取
    在这里要注意的是要把队列对象作为参数分别传给两个进程
    2,生产者消费者模型
    问题:解决供需不平衡的问题
    生产者:生产或者制造数据的 做包子的
    消费者:来筛选或者处理数据 买包子的
    案列:(不能让阻塞在data = q.get()位置)
    from multiprocessing import Process,JoinableQueue,Queue
    import time
    import random

    def scz(name,food,q):
    for i in range(0,10):
    data = ('%s生产了%s包子%s'% (name,food,i))
    time.sleep(0.5)
    q.put(data)
    print(data)


    def xfz(name,q):
    while True:
    data = q.get()
    if data == None: break # 如果data为None,说明队列中的数据已被取完
    print('%s 吃掉了%s包子'% (name,data))
    time.sleep(random.random())
    q.task_done() # 告诉队列从队列中已取出一个数据,并且已经全部处理完毕,结束任务 *****


    if __name__ == '__main__':
    # q = Queue()
    q = JoinableQueue() # *******
    p = Process(target=scz, args=('111', '牛肉馅', q))
    p1 = Process(target=scz, args=('盘龙', '白菜馅', q))
    c = Process(target=xfz, args=('开门', q))
    c1 = Process(target=xfz, args=('芝麻', q))
    c.daemon = True
    c1.daemon = True
    p.start()
    p1.start()

    c.start()
    c1.start()
    #这种方法太low了
    # p.join() # 确保生产者确确实实生产完了
    # p1.join() # 确保生产者确确实实生产完了
    # q.put(None) # 生产者生产完在队列增加一个值 None, 当取值取到None时说明队列中的数据取完了
    # q.put(None) # 一个消费者用一个None,两个消费者就得用两个None ,一个消费者只要接受到none,立马结束!
    # 高级方法
    p.join() # 确保生产者确确实实生产完了
    p1.join()

    q.join() # 等到队列中的数据全部被取出 *******
    3,线程

    1,线程:最小的执行单位
    2,进程:资源单位
    将内存比作工厂,那么进程就是车间,线程就是车间里的流水线
    ps:每个进程都自带一个主线程,线程是最小的执行单位,进程只是为了给线程提供资源或者代码
    在进程中,每个线程都是共享进程资源
    开启线程的销号要远远小于进程
    进程:开辟内存空间,太耗资源
    拷贝代码: 耗资源
    开启线程的两种方式:
    ps:开线程不需要在__main__代码块内 但是习惯性的还是写在__main__代码块内
    from threading import Thread
    import time

    def task(name):
    print('tttttu%s'% name)
    time.sleep(1)
    print('11111')

    p = Thread(target=task,args=('teek',))
    p.start() 告诉操作系统开辟一个线程 线程的开销远远小于进程
    print('zhu')
    第二种方式:
    class MyThread(Thread):
    def __init__(self,name):
    super().__init__()
    self.name = name

    def run(self):
    print("%s 是个大帅哥!"% self.name)
    time.sleep(0.1)
    print('但是%s疯了!'% self.name)

    p = MyThread('张文诶诶')
    p.start() # 启动线程
    print('zhu')
    线程的其他方法:
    from threading import Thread,current_thread,active_count
    1,current_thread 查看主线程或者子线程
    print('子current_thread:',current_thread().name)
    线程没有自主之分,都是平等的,在这里为了区分,才这样讲
    2,active_count 查看线程是否存活
    print('当前正在活跃的线程数',active_count())
    3,获取子线程号
    print('子',os.getpid())
    守护线程:
    主线程的结束也就意味着进程的结束
    主线程必须等待其他非守护线程的结束才能结束
    (意味子线程在运行的时候需要使用进程中的资源,而主线程一旦结束了资源也就销毁了)
    案列:
    from threading import Thread
    import time
    def task(i):
    time.sleep(i)
    print('tt’)

    t = Thread(target=task,args=(1,))
    t.daemon = True
    t.start()
    print('主') 主

    4, 线程间通信
    同一个进程的资源所有线程都可用,即数据共享
    money = 666
    def task():
    global money
    money = 999


    t = Thread(target=task)
    t.start()
    t.join()
    print(money)
    5,线程互斥锁:
    当多个线程或者进程想要操作同一份数据时,必须加锁,防止数据错乱!
    案列:
    from threading import Thread,Lock
    import time
    n = 100
    def task(m):
    global n
    m.acquire()
    tmp = n
    time.sleep(0.1)
    n = tmp -1
    m.release()

    tt = []
    m = Lock()
    for i in range(100):
    t = Thread(target=task,args=(m,))
    t.start()
    tt.append(t)
    for t in tt:
    t.join()
    print(n)
  • 相关阅读:
    阅读代码
    openSips
    rc.local 问题
    MyBatis框架使用(一)
    【数据结构杂谈】
    【AGC052A】
    【杜教筛学习笔记】
    CF618F Double Knapsack
    [NOI2016] 循环之美
    【BZOJ 4668 冷战】
  • 原文地址:https://www.cnblogs.com/Fzhiyuan/p/11342037.html
Copyright © 2020-2023  润新知