多进程

# join()
    # 阻塞等待子进程的结束

import time
from multiprocessing import Process

# =========运行完了和10个*是会先被打印的,20个*后面再打印
# def func(arg1, arg2):
#     print('*' * arg1)
#     time.sleep(5)
#     print('*' * arg2)
#
# if __name__ == '__main__':
#     p = Process(target=func, args=(10, 20))
#     p.start()
#     print('===========: 运行完了')


# 现在想让20个*打印完了,在执行父进程的===运行完了
# =========运行完了和10个*是会先被打印的,20个*后面再打印
def func(arg1, arg2):
    print('*' * arg1)
    time.sleep(5)
    print('*' * arg2)

if __name__ == '__main__':
    p = Process(target=func, args=(10, 20))
    p.start()   # 启动子进程
    print('hahaha')
    p.join()    # 阻塞等待子进程的结束
    print('===========: 运行完了')

 

  2.开启多个进程的方法

# 同时开启多个子进程

import time
import os
from multiprocessing import Process

# 开启多进程的一种方法
# def func(arg1, arg2):
#     print(os.getpid(), '*' * arg1)
#     time.sleep(5)
#     print(os.getpid(), '*' * arg2)
#
# if __name__ == '__main__':
#     p1 = Process(target=func, args=(5, 10))
#     p2 = Process(target=func, args=(4, 6))
#
#     p1.start()
#     p2.start()
#
#     # for i in range(10):
#     #     p = Process(target=func, args=(2 * i, 5 *i))
#     #     p.start()
#
#     print('haha')
#
#     p1.join()
#     p2.join()
#
#     print('父进程执行完了')
# --------------------------------------------------------

# # 开启多进程的方法也可以用for,但无法使得子进程全部结束后再打印父进程执行完了
# def func(arg1, arg2):
#     print(os.getpid(), '*' * arg1)
#     time.sleep(5)
#     print(os.getpid(), '*' * arg2)
#
# if __name__ == '__main__':
#     for i in range(10):
#         p = Process(target=func, args=(2 * i, 5 *i))
#         p.start()
#
#     print('父进程执行完了')

# 开启多进程的方法也可以用for,此种方法可使得子进程全部结束后再打印父进程执行完了
def func(arg1, arg2):
    print(os.getpid(), '*' * arg1)
    time.sleep(5)
    print(os.getpid(), '*' * arg2)

if __name__ == '__main__':
    p_lst = []  # 创建了一个list
    for i in range(10):
        p = Process(target=func, args=(2 * i, 5 *i))
        p_lst.append(p) # 将创建的每个子进程对象加入到list列表中
        p.start()
    [p.join() for p in p_lst]   # 遍历列表中的每个子进程对象,都调用join()阻塞等待子进程的结束

    print('父进程执行完了')

 

  3.使用自定义类继承Process类,重写run方法和init方法进行启动进程的方法

# 第二种创建多进程的方式
    # 创建一个自定义类,继承自Process类
    # 必须实现以个run方法,run方法中的代码是在子进程中执行的代码
    # 开启子进程的方式是子进程类对象调用start()

import os
import time
from multiprocessing import Process


# 创建一个类,继承自Process进程类,并实现一个run方法,run方法中的代码是在子进程中执行的代码
# class MyProcess1(Process):
#     def run(self):
#         print(os.getpid())
#         print(self.pid) # 查看当前进行的pid
#         print(self.name) # 查看当前进行的进程名
#
#
# if __name__ == '__main__':
#     print('主进程pid %s' % os.getpid())
#     p1 = MyProcess1()
#     p2 = MyProcess1()
#
#     p1.start()  # 启动进程类中的继承,运行了run方法
#     p2.start()
#
#     p1.join()
#     p2.join()
#
#     print('父进程执行完了')

# 如何传参数呢,下面的方式进行传参,如果需要传参,需要重写一个init方法,并运行将父类init将其属性继承过来,如果不需要传参,则不用重新init函数,只重写run方法即可
class MyProcess1(Process):
    def __init__(self, arg1, arg2):
        super().__init__()  # 调用父类Process的init方法,因为有很多属性可能在其他我们看不到的地方被使用,所以当我们要重新初始化属性时,要将父类的属性弄过来
        self.arg1 = arg1
        self.arg2 = arg2

    def run(self):
        print(os.getpid())
        print(self.pid) # 查看当前进行的pid
        print(self.name) # 查看当前进行的进程名
        print(self.arg1)
        print(self.arg2)


if __name__ == '__main__':
    print('主进程pid %s' % os.getpid())
    p1 = MyProcess1(2, 5)   # 2与5作为参数
    p2 = MyProcess1(7, 8)

    p1.start()  # 启动进程类中的继承,运行了run方法
    p2.start()

    p1.join()
    p2.join()

    print('父进程执行完了')

 

  4.进程与进程之间数据隔离问题,进程与进程之间数据是隔离的,想要互相交互数据需要通过其他手段(管道,后面再说)

# 进程与进程之间数据是隔离开的
    # 父进程与子进程之间数据也是隔离开的
    # 进程与进程之间如果不通过特殊的手段(管道),数据是完全隔离的


# 证明父进程与子进程之间的数据也是隔离开的,全局变量无法共用
from multiprocessing import Process
import os

def func():
    global n    # 声明使用全局的n
    n = 0   # 将n赋值为0  实际上是定义了一个n,赋值为0
    print('pid : %s' % os.getpid(), n)  # 0

if __name__ == '__main__':

    n = 100
    p = Process(target=func)
    p.start()
    p.join()
    print('主进程pid: %s' % os.getpid(), n)    # 100

 

  5.使用多进程实现socket服务端的并发,只为了演示多进程,当客户端多时,会存在性能问题。

  5.1 server.py

# 使用多进程实现socket服务端的并发

# 下面这种方法,只能同时处理一个客户端
# import socket
#
# sk = socket.socket()
#
# sk.bind(('127.0.0.1', 8080))
#
# sk.listen()
#
# while True:
#     conn, addr = sk.accept()
#     ret = '你好'.encode('utf-8')
#     conn.send(ret)
#     msg = conn.recv(1024).decode('utf-8')
#     print(msg)
#     conn.close()
#
# sk.close()


# 下面这种方法,服务端可以实现并发,虽然此种方法可以实现并发,来一个客户端上来就启一个进程与其对应,但此种方法在客户端多时,在性能上会存在问题。socketserver相对于多进程方式实现的并发会好一些
import socket
from multiprocessing import Process

def serve(conn, addr):
    ret = '你好'.encode('utf-8')
    conn.send(ret)
    msg = conn.recv(1024).decode('utf-8')
    print(msg)
    conn.close()

if __name__ == '__main__':
    sk = socket.socket()
    sk.bind(('127.0.0.1', 8080))
    sk.listen()
    while True:
        conn, addr = sk.accept()    # 当一个客户端连接上来时,得到客户端连接描述符和客户端ip端口
        p = Process(target=serve, args=(conn, addr))    # 就创建一个子进程,将客户端连接符和客户端地址以参数形式传递给子进程
        p.start()   # 启动子进程

  5.2 client.py

import socket

sk = socket.socket()

sk.connect(('127.0.0.1', 8080))


msg = sk.recv(1024).decode('utf-8')
print(msg)

inputinfo = input('>>>').encode('utf-8')

sk.send(inputinfo)

sk.close()

 

  6.关于多进程的补充

from multiprocessing import Process


def func():
    num = input('>>>')  # 不可以,报错
    print(num)

if __name__ == '__main__':
    Process(target=func).start()

# 进程同步控制
    # 锁/信号量/事件

# 进程间通信
    # 队列和管道

# 进程间的数据共享
    # multiProcess.Manager

# 进程池和multiprocessPool

 

转载于:https://www.cnblogs.com/whylinux/p/9800584.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值