zoukankan      html  css  js  c++  java
  • 网络编程--进程之间的数据隔离问题,守护进程

    进程与进程之间的数据是隔离的
          内存空间是不能共享的
       所以要想进行通信,必须借助其他手段  
       且这两个进程都是自愿的
       子进程的执行结果父进程获取不到
     父进程如何获取子进程的执行结果???
      父子进程之间通过socket通信
    from  multiprocessing import  Process
    
    n = 100
    def func():
        global n
        n = n-1
        return 111
    
    if __name__ == '__main__':
        n_l = []
        for i in range(100):
            p = Process(target=func)
            p.start()
            n_l.append(p)
        for p in n_l : p.join()
        print(n)

    2守护进程

      设置守护进程会在主进程的代码执行完毕之后直接结束,无论守护进程是否执行完毕

    应用场景 

       报活 主进程还活着
          100台机器 100个进程  10000进程
           应用是否在正常工作 - 任务管理器来查看
           守护进程如何向监测机制报活???send/写数据库
           为什么要用守护进程来报活呢?为什么不用主进程来工作呢???
             守护进程报活几乎不占用CPU,也不需要操作系统去调度
                 主进程能不能严格的每60s就发送一条信息

    例一:

    import time
    from multiprocessing import Process
    def func1():
        print("begin")
        time.sleep(3)
        print("wahaha")
    if __name__ == '__main__':
        p=Process(target=func1)
        p.daemon=True
        #守护进程的属性, 默认是False, 如果设置成True, 就表示设置这个子进程为一个守护进程
        #     # 设置守护进程的操作应该在开启子进程之前
        p.start()
        time.sleep(1)
        print("主程序")

    例二:

    import time
    from multiprocessing import Process
    def func1():
        print("begin")
        time.sleep(3)
        print("wahaha")
    
    def  func2():
        while True:
            print("in finc2")
            time.sleep(0.5)
    
    if __name__ == '__main__':
        Process(target=func1).start()
        p=Process(target=func2)
        p.daemon=True
        #守护进程的属性, 默认是False, 如果设置成True, 就表示设置这个子进程为一个守护进程
        #     # 设置守护进程的操作应该在开启子进程之前
        p.start()
        time.sleep(1)
        print("主程序")
        #设置成守护进程之后
        #会有什么效果呢?
        # 守护进程会在主进程的代码执行完毕之后直接结束,无

    所有的进程的基本使用

    进程: 同一时刻可以做很多事情,互相之间不影响

    socket tcp  server

    采用多进程的知识点 来解决原生 socket 同一时刻只能和一个conn来进行通信

    server端

    import socket
    from multiprocessing import Process
    def talk(conn):
        try:
            while True:
                conn.send(b'hello')
                print(conn.recv(1024))
        finally:
            conn.close()
    if __name__ == '__main__':
        sk = socket.socket()
        sk.bind(('127.0.0.1',9091))
        sk.listen()
        try:
            while True:
                conn,addr = sk.accept()
                Process(target=talk,args=(conn,)).start()
        finally:
            sk.close()

    client端

    import socket
    import os
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',9091))
    
    while True:
        print(sk.recv(1024))
        sk.send(str(os.getpid()).encode('utf-8'))

    锁 重中之重***********************************

    当多个进程共享一段数据的时候,数据会出现不安全的现象,
    需要加锁来维护数据的安全性

    lock = Lock() # 创造了一把锁
    lock.acquire() # 获取了这把锁的钥匙
    lock.release() # 归还这把锁的钥匙

    例一

    from multiprocessing import Lock
    from multiprocessing import Process
    import json
    import time
    from multiprocessing import Lock
    from multiprocessing import Process
    def search(i):
        with open('db','r') as f:count_dic = json.load(f)
        time.sleep(0.2)
        print('person %s 余票 : %s张'%(i,count_dic['count']))
    
    def buy(i):
        with open('db','r') as f:count_dic = json.load(f)
        time.sleep(0.2)
        if count_dic['count'] > 0:
            count_dic['count'] -= 1
            print('person %s 购票成功'%i)
        time.sleep(0.2)
        with open('db','w') as f:json.dump(count_dic,f)
    
    def task(i,lock):
        search(i)
        lock.acquire()   # 如果之前已经被acquire了 且 没有被release 那么进程会在这里阻塞
        buy(i)
        lock.release()
    
    if __name__ == '__main__':
        lock = Lock()
        for i in range(10):
            p = Process(target=task,args=(i,lock))
            p.start()

    例二  信号量 多吧钥匙对应一把锁 lock+count

     ktv
    4个小房子
    10个人站在房子外面要进去玩儿

    from multiprocessing import Process
    from multiprocessing import Semaphore  
    
    import time
    import random
    from multiprocessing import Process,Semaphore
    def ktv(num,sem):
        sem.acquire()
        print('person%s进入了ktv' % num)
        time.sleep(random.randint(1,4))
        print('person%s走出了ktv' % num)
        sem.release()
    if __name__ == '__main__':
        sem = Semaphore(4)
        for i in range(10):
            p = Process(target=ktv,args=(i,sem))
            p.start()

    3 事件

    wait() 方法 等待
    阻塞  如果这个标志是False 那么就阻塞
    非阻塞  如果这个标志是True 那么就非阻塞
    查看标志 is_set()
     修改标志

      set()将标志设置为True

      clear() 将标志设置为False

    e = Event()
     print(e.is_set())  # 在事件的创建之初 默认是False
     e.set()            # 将标志设置为True
     print(e.is_set())
     e.wait()           # 相当于什么都没做pass
     e.clear()          # 将标志设置为False
      e.wait()           # 永远阻塞
     e.wait(timeout=10) # 如果信号在阻塞10s之内变为True,那么不继续阻塞直接pass,
                        # 如果就阻塞10s之后状态还是没变,那么继续,
    print(e.is_set())  # 无论前面的wait的timeout是否通过,我的状态都不会因此改变

    红绿灯模型 

    控制交通灯的进程

    from multiprocessing import Event,Process
    import time
    import random
    def traffic_light(e):
        print('33[1;31m 红灯亮33[0m')
        while True:
            time.sleep(2)
            if e.is_set():
                print('33[1;31m 红灯亮33[0m')
                e.clear()
            else:
                print('33[1;32m 绿灯亮33[0m')
                e.set()
    
    
    # 车 等或者通过
    def car(id,e):
        if not e.is_set():
            print('car %s 等待' % id)
            e.wait()
        print('car %s 通过'%id)
    
    def police_car(id,e):
        if not e.is_set():
            e.wait(timeout = 0.5)
        print('police car %s 通过' % id)
    
    # 主进程 启动交通控制灯 启动车的进程
    if __name__ == '__main__':
        e = Event()
        p = Process(target=traffic_light,args=(e,))
        p.start()
        car_lst = [car,police_car]
        for i in range(20):
            p = Process(target=random.choice(car_lst), args=(i,e))
            p.start()
            time.sleep(random.randrange(0,3,2))
     
  • 相关阅读:
    认识岗位-带你一起偷窥产品经理的日常
    SpringBoot单元测试踩坑
    Oracle“ORA-38104: 无法更新ON子句中引用的列”解决方式
    SXSSFWorkbook使用补充
    JAVA复制字符串并用指定字符串拼接
    一个简单for循环的时间复杂度
    SXSSFWorkbook的简单使用
    AOP行为日志
    antV G2 为柱状图添加背景颜色
    AntV G2 图表tooltip重命名
  • 原文地址:https://www.cnblogs.com/daien522556/p/9366728.html
Copyright © 2011-2022 走看看