多进程

什么是进程:正在运行的程序

主进程要等待子进程结束后才结束,因为主进程要等待子进程结束后帮他们收尸

创建进程的类:

Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)

强调:
1. 需要使用关键字的方式来指定参数
2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号
参数介绍:
1 group参数未使用,值始终为None
2 target表示调用对象,即子进程要执行的任务 
3 args表示调用对象的位置参数元组,args=(1,2,'egon',) 
4 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
5 name为子进程的名称
方法介绍:
 1 p.start():启动进程,并调用该子进程中的p.run() 
 2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法   
 3 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
 4 p.is_alive():如果p仍然运行,返回True 
 5 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
属性介绍:
1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置 
2 p.name:进程的名称 
3 p.pid:进程的pid 
4 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可) 
5 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)

开启子进程的方式一:
from multiprocessing import Process
import time,os,random
 
 
def work(name):
    print('%s is running' %name)
    time.sleep(2)
    print('%s end' %name)

if __name__ == '__main__':
    p=Process(target=work,args=('alex',))
    p.start()
    print('')
开启子进程的方式二:
class Work(Process):
    def __init__(self,name):
        super().__init__()  # 重用父类的方法
        self.name=name    # 定义自己的名字
    def run(self):
        print('%s is piaoing' %self.name)
        time.sleep(2)
        print('%s piao end' %self.name)

if __name__ == '__main__':
    p=Work('wusir')
    p.start()
    print('')

开启多个子进程:

# 开启多个子进程
def work(name):
    print('%s is running' %name)
    time.sleep(2)
    print('%s end' %name)

if __name__ == '__main__':
    p1=Process(target=work,args=('alex',))
    p2=Process(target=work,args=('alexx',))
    p3=Process(target=work,args=('alexc',))
    p1.start()
    p2.start()
    p3.start()
    print('')
 1 def work():
 2     print('子进程的pid:%s,父进程的pid:%s' %(os.getpid(),os.getppid()))
 3     time.sleep(1000)
 4 
 5 if __name__ == '__main__':
 6     p1=Process(target=work)
 7     p2=Process(target=work)
 8     p3=Process(target=work)
 9     p1.start()
10     p2.start()
11     p3.start()
12     print('',os.getpid(),os.getppid())
13     time.sleep(100000)
查看正在运行的进程号
def work():
    print('子进程的pid:%s,父进程的pid:%s' %(os.getpid(),os.getppid()))
    time.sleep(1000)

if __name__ == '__main__':
    p1=Process(target=work)
    p2=Process(target=work)
    p3=Process(target=work)
    p1.start()
    p2.start()
    p3.start()
    print('主',os.getpid(),os.getppid())
    time.sleep(100000)

  socket通信变成并发的形式:

import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

phone.connect(('127.0.0.1',8083))
while True:  # 用户循环发送数据
    msg=input('>>: ').strip()
    if not msg:continue   # 因为服务端不会对一个空数据进行操作,所以要限制用户输入为空
    phone.send(msg.encode('utf-8'))
    data=phone.recv(1024)  # 接收服务端传来的数据
    print(data.decode('utf-8'))

phone.close()
client
import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

phone.connect(('127.0.0.1',8083))
while True:  # 用户循环发送数据
    msg=input('>>: ').strip()
    if not msg:continue   # 因为服务端不会对一个空数据进行操作,所以要限制用户输入为空
    phone.send(msg.encode('utf-8'))
    data=phone.recv(1024)  # 接收服务端传来的数据
    print(data.decode('utf-8'))

phone.close()
import socket
from multiprocessing import Process
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8083))  # 绑定ip和端口
phone.listen(5)  # 等待连接的个数,最大监听数
print('starting...')

def talk(conn):
    while True:
        try:  # 解决客户端异常断开
            data=conn.recv(1024)
            print(data)
            if not data:break
            conn.send(data.upper())
        except Exception:
            break
    conn.close()
if __name__ == '__main__':  # windows下start进程一定要写到这下面
    while True:
        conn, addr = phone.accept()
        print('IP:%s,PORT:%s' % (addr[0], addr[1]))
        p=Process(target=talk,args=(conn,))
        p.start()
        print('>>>>>::')
phone.close()
server
import socket
from multiprocessing import Process
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8083))  # 绑定ip和端口
phone.listen(5)  # 等待连接的个数,最大监听数
print('starting...')

def talk(conn):
    while True:
        try:  # 解决客户端异常断开
            data=conn.recv(1024)
            print(data)
            if not data:break
            conn.send(data.upper())
        except Exception:
            break
    conn.close()
if __name__ == '__main__':  # windows下start进程一定要写到这下面
    while True:
        conn, addr = phone.accept()
        print('IP:%s,PORT:%s' % (addr[0], addr[1]))
        p=Process(target=talk,args=(conn,))
        p.start()
        print('>>>>>::')
phone.close()
每来一个客户端,都在服务端开启一个进程,如果并发来一个万个客户端,要开启一万个进程吗,你自己尝试着在你自己的机器上开启一万个,10万个进程试一试。
解决方法:进程池
 
s
json方法
from multiprocessing import Process
import time
def work(name,n):
    print('%s is piaoing' %name)
    time.sleep(n)
    print('%s piao end' %name)

if __name__ == '__main__':
    start_time=time.time()
    p1=Process(target=work,args=('alex',1))
    p2=Process(target=work,args=('wupeiqi',2))
    p3=Process(target=work,args=('yuanhao',3))
    # p1.start()
    # p2.start()
    # p3.start()

    # p3.join() #主进程等,等待子进程结束后,主进程再执行后面的代码
    # p2.join() #主进程等,等待子进程结束后,主进程再执行后面的代码
    # p1.join() #主进程等,等待子进程结束后,主进程再执行后面的代码

    p_l=[p1,p2,p3]
    for p in p_l:
        p.start()
        
    for p in p_l:
        p.join()

    stop_time=time.time()
    print('',(stop_time-start_time))
# 必须明确:p.join()是让谁等?
# 很明显p.join()是让主线程等待p的结束,卡住的是主线程而绝非进程p,
# 主进程等待所有子进程执行完毕,必须在close或terminate之后
ss
进程的其他方法
from multiprocessing import Process
import time
def work(name,n):
    print('%s is piaoing' %name)
    time.sleep(n)
    print('%s piao end' %name)

if __name__ == '__main__':
    p1=Process(target=work,args=('alex',1))
    p1.start()
    p1.terminate()
    time.sleep(1)
    print(p1.is_alive()) # 关闭进程不会立即关闭,所以iis_alive立刻查看的结果有可能还存活
    print('')
    print(p1.name)
    print(p1.pid)

 

 

 
 
 












 

转载于:https://www.cnblogs.com/sunxiansheng/p/7647147.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值