网络编程--进程之间的数据隔离问题,守护进程

进程与进程之间的数据是隔离的
      内存空间是不能共享的
   所以要想进行通信,必须借助其他手段  
   且这两个进程都是自愿的
   子进程的执行结果父进程获取不到
 父进程如何获取子进程的执行结果???
  父子进程之间通过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('\033[1;31m 红灯亮\033[0m')
    while True:
        time.sleep(2)
        if e.is_set():
            print('\033[1;31m 红灯亮\033[0m')
            e.clear()
        else:
            print('\033[1;32m 绿灯亮\033[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))
 

猜你喜欢

转载自www.cnblogs.com/daien522556/p/9366728.html