首页 > 系统相关 >【补充】进程理论:开设多进程的方式、多进程实现服务端并发、join实现并发

【补充】进程理论:开设多进程的方式、多进程实现服务端并发、join实现并发

时间:2024-05-23 20:51:18浏览次数:11  
标签:__ join name work 并发 time 进程 main

【补充】进程理论

【一】开设多进程的两种方式

【1】在Windows上启动子进程

#必须将启动入口放到 if __name__ == '__main__':
'''
由于Windows没有fork,多处理模块启动一个新的Python进程并导入调用模块。 
如果在导入时调用Process(),那么这将启动无限继承的新进程(或直到机器耗尽资源)。 
这是隐藏对Process()内部调用的原,使用if **name** == “**main** ”,
这个if语句中的语句将不会在导入时被调用。
'''

【2】multiprocessing使用

# 【二】multiprocessing使用
# 【1】导入模块
import multiprocessing
import random
import time


# 【2】创建子进程程序

def work(name):
    print(f"{name} is starting \n")
    sleep_time = random.randint(1, 6)
    print(f"{name} is sleeping {sleep_time} s \n")
    time.sleep(sleep_time)
    print(f"{name} is ending \n")


# 【3】制作多进程的启动入口
# (1)方式一:同过multiprocessing的对象启动
def main_object():
    # (1)实例化得到子进程对象
    task_1 = multiprocessing.Process(
        # target 就是需要启动的子进程的函数名
        target=work,
        # args 传入的位置参数,位置参数必须带 , 元组类型
        args=("work_1",)
    )
    task_2 = multiprocessing.Process(
        target=work,
        kwargs={'name': 'work_2'}
    )
    # (2)启动子进程
    # p.start()
    task_1.start()
    task_2.start()
    
    
    

    class MyProcess(multiprocessing.Process):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        print(f"{self.name} is starting \n")
        sleep_time = random.randint(1, 6)
        print(f"{self.name} is sleeping {sleep_time} s \n")
        time.sleep(sleep_time)
        print(f"{self.name} is ending \n")


def main_class():
    # 创建子进程一
    task_1 = MyProcess(name='work_1')
    task_2 = MyProcess(name='work_2')

    #
    task_1.start()
    task_2.start()


# 【4】在主程序入口中启动当前子进程
if __name__ == '__main__':
    start_time = time.time()
    print(f"这是主进程 __main__ 开始 :>>>> \n")
    # main_object()
    main_class()
    print(f"这是主进程 __main__ 结束 :>>>> \n")
    end_time = time.time()
    print(f'总耗时 :>>>> {end_time - start_time}s')

    # 这是主进程 __main__ 开始 :>>>>
    # 这是主进程 __main__ 结束 :>>>>
    # work_1 is starting
    # work_1 is sleeping 2 s
    # work_2 is starting
    # work_2 is sleeping 3 s
    # work_1 is ending
    # work_2 is ending

    # 执行流程
    # 先启动主进程
    # 分别启动子线程
    # 主进程结束
    # 等待子进程分别结束

【二】子进程之间的数据是隔离的

import multiprocessing

# 多进程:两个甚至多个进程
# 多进程中的子进程之间的数据不共享
money = 9999


def change_money(name):
    global money
    print(f'{name} 原始的money :>>>> {money}')
    # 在局部修改上面的 money 局部修改不可变数据类型
    # 需要 提升变量等级 global
    money = 8888
    print(f'{name} 当前子进程修改后的money :>>>> {money}')


def main():
    for i in range(10):
        task = multiprocessing.Process(
            target=change_money,
            args=(i,)
        )
        task.start()


if __name__ == '__main__':
    main()

【三】多进程实现服务端并发

import socket

client = socket.socket()
ip = '127.0.0.1'
port = 8802
addr = (ip, port)
client.connect(addr)

while True:
    letter = input("请输入字母:>>>> ").strip()
    client.send(letter.encode())
    if letter == 'q':
        client.close()
        break
    data = client.recv(1024)
    print(f"这是来自服务单的数据 :>>>> {data.decode()}")

【1】未实现并发

import socket

server = socket.socket()

ip = '127.0.0.1'
port = 8802
addr = (ip, port)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(addr)

server.listen(1)
conn, addr = server.accept()
while True:
    data = conn.recv(1024)
    if data.decode() == 'q':
        conn.close()
    print(f'这是来自客户端的数据 :>>>>{data.decode()}')

    conn.send(data.decode().upper().encode())

【2】实现并发

import multiprocessing
import socket

server = socket.socket()
ip = '127.0.0.1'
port = 8802
addr = (ip, port)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(addr)
server.listen(0)


def run(conn):
    while True:
        data = conn.recv(1024)
        if data.decode() == 'q':
            conn.close()
        print(f'这是来自客户端的数据 :>>>>{data.decode()}')

        conn.send(data.decode().upper().encode())


def main():
    while True:
        conn, addr = server.accept()
        task = multiprocessing.Process(target=run, args=(conn,))
        task.start()


if __name__ == '__main__':
    main()

【四】join实现并发

【1】主进程结束子进程未结束

# 【一】multiprocessing使用
# 【1】导入模块
import multiprocessing
import random
import time


# 【2】创建子进程程序

def work(name):
    print(f"{name} is starting \n")
    sleep_time = random.randint(1, 6)
    print(f"{name} is sleeping {sleep_time} s \n")
    time.sleep(sleep_time)
    print(f"{name} is ending \n")


# 【3】制作多进程的启动入口
# (1)方式一:同过multiprocessing的对象启动
def main_object():
    # 这个生成式在创建多个子进程
    task_list = [multiprocessing.Process(
        # target 就是需要启动的子进程的函数名
        target=work,
        # args 传入的位置参数,位置参数必须带 , 元组类型
        args=(f"work_{i}",)
    ) for i in range(5)]
    # (2)启动子进程
    task_list = [task.start() for task in task_list]


if __name__ == '__main__':
    start_time = time.time()
    print(f"这是主进程 __main__ 开始 :>>>> \n")
    main_object()
    print(f"这是主进程 __main__ 结束 :>>>> \n")
    end_time = time.time()
    print(f'总耗时 :>>>> {end_time - start_time}s')

    # 这是主进程 __main__ 开始 :>>>>
    # 这是主进程 __main__ 结束 :>>>>
    # work_1 is starting
    # work_1 is sleeping 5 s
    # work_2 is starting
    # work_2 is sleeping 4 s
    # work_4 is starting
    # work_4 is sleeping 4 s
    # work_0 is starting
    # work_0 is sleeping 2 s
    # work_3 is starting
    # work_3 is sleeping 2 s
    # work_0 is ending
    # work_3 is ending
    # work_2 is ending
    # work_4 is ending
    # work_1 is ending

【2】主进程等待子进程结束(join串行)

# 【一】multiprocessing使用
# 【1】导入模块
import multiprocessing
import random
import time


# 【2】创建子进程程序

def work(name):
    print(f"{name} is starting \n")
    sleep_time = random.randint(1, 6)
    print(f"{name} is sleeping {sleep_time} s \n")
    time.sleep(sleep_time)
    print(f"{name} is ending \n")


# 【3】制作多进程的启动入口
# (1)方式一:同过multiprocessing的对象启动
def main_object():
    # 这个生成式在创建多个子进程
    task_list = [multiprocessing.Process(
        # target 就是需要启动的子进程的函数名
        target=work,
        # args 传入的位置参数,位置参数必须带 , 元组类型
        args=(f"work_{i}",)
    ) for i in range(5)]
    # (2)启动子进程
    for task in task_list:
        task.start()
        task.join()


if __name__ == '__main__':
    start_time = time.time()
    print(f"这是主进程 __main__ 开始 :>>>> \n")
    main_object()
    print(f"这是主进程 __main__ 结束 :>>>> \n")
    end_time = time.time()
    print(f'总耗时 :>>>> {end_time - start_time}s')

    # 这是主进程 __main__ 开始 :>>>>
    # 这是主进程 __main__ 结束 :>>>>
    # 并行变串行 ; 所有主进程等待所有子进程结束后才会结束
    # 依次执行每一个子进程
    # 并且是拿到上一个子进程的结果后才会执行下一个子进程
    # 总耗时 :>>>> 22.509196758270264s

【3】主进程等待子进程结束(join并行)

# 【一】multiprocessing使用
# 【1】导入模块
import multiprocessing
import random
import time


# 【2】创建子进程程序

def work(name):
    print(f"{name} is starting \n")
    sleep_time = random.randint(1, 6)
    print(f"{name} is sleeping {sleep_time} s \n")
    time.sleep(sleep_time)
    print(f"{name} is ending \n")


# 【3】制作多进程的启动入口
# (1)方式一:同过multiprocessing的对象启动
def main_object():
    task_list = []
    # 这个生成式在创建多个子进程
    for i in range(5):
        task = multiprocessing.Process(
            # target 就是需要启动的子进程的函数名
            target=work,
            # args 传入的位置参数,位置参数必须带 , 元组类型
            args=(f"work_{i}",)
        )
        task.start()
        task_list.append(task)
    # (2)启动子进程
    for task in task_list:
        task.join()


if __name__ == '__main__':
    start_time = time.time()
    print(f"这是主进程 __main__ 开始 :>>>> \n")
    main_object()
    print(f"这是主进程 __main__ 结束 :>>>> \n")
    end_time = time.time()
    print(f'总耗时 :>>>> {end_time - start_time}s')

    # 这是主进程 __main__ 开始 :>>>>
    # 这是主进程 __main__ 结束 :>>>>
    # 总耗时 :>>>> 5.176285266876221s
    # 并行
    # 并且主进程等待所有子进程结束后再结束
    # 耗时是最长的子进程的耗时

标签:__,join,name,work,并发,time,进程,main
From: https://www.cnblogs.com/chosen-yn/p/18209321

相关文章

  • 进程理论、进程与程序的区别、调度算法、进程的创建,状态,终止
    【一】进程理论【1】什么是进程(1)理论正在进行的一个过程或者说一个任务而负责执行任务则是cpu(2)单任务一个单独的任务单核+多道,实现多个进程的并发执行一段时间段只能做一件事:铺床、吹头发、睡觉(cpu同一时间只能干一个活)(3)多任务一段时间可以做很多件事铺......
  • 10-2-uptime查看系统负载-top动态管理进程
    10.2.1uptime查看CPU负载工具 任务队列的平均长度是什么?案例1:找出当前系统中,cpu负载过高的服务器。服务器1:loadaverage:0.15,0.08,0.011核服务器2:loadaverage:4.15,6.08,6.011核服务器3:loadaverage:10.15,10.08,10.01......
  • python多进程感悟
    对于大量的测试数据,使用多进程时(例如8个进程),最好使用queue来消费数据,不要将测试数据分为8个list,分别送入不同的进程中,因为这样可以避免极端情况出现。例如,每个测试数据处理起来耗时不一样,你刚好把耗时比较长的数据分了同一个list,就会导致其他的进程也会一直等待该进程的完成。......
  • 10.1 进程概述和ps管理进程
    10.1.1什么是进程?进程是已启动的可执行程序的运行实例,进程有以下组成部分:(1.已分配内存的地址空间;(2.安全属性,包括所有权凭据和特权;(3.程序代码的一个或多个执行线程;(4.进程状态程序:二进制文件,静态/bin/date,/usr/sbin/sshd......
  • mysql left join 查询右表的最新记录
    leftjoin关联查询右表多条记录只保留最新的一条,可以通过max+groupby实现sql如下:SELECTt1.*,t4.maxEndDate,t4.Q_STANDARD,t4.COAL_CLASFROMpub_item_unit_infot1LEFTJOIN(SELECTt3.id,t3.INDEX_CODE,t3......
  • windows下使用redis解决.net6.0下人工调用接口时分配位置的并发问题
    使用了nuget包包括了:CSRedisCore,StackExchange.Redis,MyStack.DistributedLocking,Microsoft.Extensions.Configuration安装Redis并注册为windows服务 直接参考这位兄弟的成果:https://www.cnblogs.com/qingheshiguang/p/17952623注册服务:配置文件appsetting.json中加上Red......
  • 一台服务器​最大并发 tcp 连接数多少?65535?
    首先,问题中描述的65535个连接指的是客户端连接数的限制。在tcp应用中,server事先在某个固定端口监听,client主动发起连接,经过三次握手后建立tcp连接。那么对单机,其最大并发tcp连接数是多少呢?如何标识一个TCP连接在确定最大连接数之前,先来看看系统如何标识一个tcp连接。系统用一个......
  • 《Linux内核完全注释》学习笔记:2.4 Linux内核进程控制
    程序是一个可执行的文件,而进程(process)是一个执行中的程序实例。利用分时技术,在Linux操作系统上同时可以运行多个进程。分时技术的基本原理:把CPU的运行时间划分成一个个规定长度的时间片(timeslice),让每个进程在一个时间片内运行。当进程的时间片用完时系统就利用调度程序......
  • 守护进程--执行长期运行的任务
    守护进程(Daemon)是一种在后台运行的进程,通常用于执行系统服务或后台任务。守护进程在系统启动时自动启动,并在系统运行期间持续运行,直到系统关闭。它们不与用户直接交互,而是通过系统调用、网络请求、或其他进程间通信机制与其他进程进行交互。守护进程的主要特点和用途如下:后台运......
  • 进程间通信(管道),多线程
    Ⅰ进程间通信(管道)【一】引入借助于消息队列,进程可以将消息放入队列中,然后由另一个进程从队列中取出。这种通信方式是非阻塞的,即发送进程不需要等待接收进程的响应即可继续执行。multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的进程间通信(IPC)方式二......