python的多进程和多线程(2)

本文介绍了Python中使用Manager实现进程间数据共享,详细阐述了进程池(pool)的优势,如避免频繁创建进程的开销,减少系统资源消耗。同时讨论了多线程的概念,指出线程间的内存共享特性及其在同步和加锁上的挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

manager数据共享

  • 通过Manager可实现进程间数据的共享。Manager()返回的manager对象会通过一个服务进程,来使其他进程通过代理的方式操作python对象。manager对象支持 list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value ,Array.
from multiprocessing import Manager, Process


def worker(dt, lt):
    for i in range(10):
        dt[i] = i*i

    lt += [x for x in range(11, 16)]




if __name__ == '__main__':
    manager = Manager()
    dt = manager.dict()
    lt = manager.list()
    p = Process(target=worker, args=(dt, lt))
    p.start()
    p.join(timeout=3)
    print(dt)
    print(lt)

#输出

{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
[11, 12, 13, 14, 15]

pool进程池

  • 一般我们是通过动态创建子进程(或子线程)来实现并发服务器的,但是会存在这样一些缺点:
      1、动态创建进程(或线程)比较耗费时间,这将导致较慢的服务器响应。
      2、动态创建的子进程通常只用来为一个客户服务,这样导致了系统上产生大量的细微进程(或线程)。进程和线程间的切换将消耗大量CPU时间。
      3、动态创建的子进程是当前进程的完整映像,当前进程必须谨慎的管理其分配的文件描述符和堆内存等系统资源,否则子进程可能复制这些资源,从而使系统的可用资源急剧下降,进而影响服务器的性能。 所以呢,就引入了进程池与线程池的概念。
      
# pool.apply_async   非阻塞,定义的进程池最大数的同时执行
# pool.apply    一个进程结束,释放回进程池,开始下一个进程

import time

import multiprocessing


def fun(msg):
    print("#########start#### {0}".format(msg))
    time.sleep(3)
    print("#########end###### {0}".format(msg))


if __name__ == '__main__':
    print("start main")
    pool = multiprocessing.Pool(processes=3)
    for i in range(1, 7):
        msg = "hello {0}".format(i)
        pool.apply_async(fun, (msg,))# 执行时间6s+
        # pool.apply(fun, (msg,))   6*3=18+#执行时间
    pool.close()#在调用join之前,要先调用close,否则会报错,close执行完不会有新的进程加入到pool
    pool.join()#join 是等待所有的子进程结束
    print("end main")

#输出
start main
#########start#### hello 1
#########start#### hello 2
#########start#### hello 3
#########end###### hello 1
#########start#### hello 4
#########end###### hello 2
#########start#### hello 5
#########end###### hello 3
#########start#### hello 6
#########end###### hello 4
#########end###### hello 5
#########end###### hello 6
end main

多线程

  • 1、多线程的理解
    多进程和多线程都可以执行多个任务,线程是进程的一部分。线程的特点是线程之间可以共享内存和变量,资源消耗少(不过在Unix环境中,多进程和多线程资源调度消耗差距不明显,Unix调度较快),缺点是线程之间的同步和加锁比较麻烦。
'''
多线程    密集型io
多线程的实现有两种方法:
方法1:
和多进程类似
方法2:
通过继承的方式
'''
import threading


def worker(args):
    print("开始子进程 {0}".format(args))
    print("结束子进程 {0}".format(args))

if __name__ == '__main__':

    print("start main")
    t1 = threading.Thread(target=worker, args=(1,))
    t2 = threading.Thread(target=worker, args=(2,))
    t1.start()
    t2.start()
    print("end main")

#输出

start main
开始子进程 1
结束子进程 1
开始子进程 2
end main
结束子进程 2

import threading

import time


class Hello(threading.Thread):
    def __init__(self, args):
        super(Hello, self).__init__()
        self.args = args

    def run(self):
        print("开始子进程 {0}".format(self.args))
        time.sleep(1)
        print("结束子进程 {0}".format(self.args))

if __name__ == '__main__':

    a = 1
    print("start main")
    t1 = Hello(1)
    t2 = Hello(2)
    t1.start()
    t2.start()
    print("end main")

#输出
start main
开始子进程 1
开始子进程 2
end main
结束子进程 2
结束子进程 1

类的方式实现

import threading

import time


class Hello(threading.Thread):
    def __init__(self, args):
        super(Hello, self).__init__()
        self.args = args
        global a
        print("a = {0}".format(a))
        a += 1

    def run(self):
        print("开始子进程 {0}".format(self.args))
        print("结束子进程 {0}".format(self.args))

if __name__ == '__main__':
    a = 1
    print("start main")
    t1 = Hello(5)
    time.sleep(3)
    t2 = Hello(5)
    t1.start()
    t2.start()
    print("#####a = {0}####".format(a))
    print("end main")

#输出
start main
a = 1
a = 2
开始子进程 5
结束子进程 5
#####a = 3####
end main
开始子进程 5
结束子进程 5

线程锁

  • 由于存在多个进程共同去修改某个数据的问题,所以必须要用到lock()
import threadpool


def hello(m, n, o):
    print("m = {0}  n={1}  o={2}".format(m, n, o))

if __name__ == '__main__':
    # 方法1
    lst_vars_1 = ['1', '2', '3']
    lst_vars_2 = ['4', '5', '6']
    func_var = [(lst_vars_1, None), (lst_vars_2, None)]
    # 方法2
    # dict_vars_1 = {'m': '1', 'n': '2', 'o': '3'}
    # dict_vars_2 = {'m': '4', 'n': '5', 'o': '6'}
    # func_var = [(None, dict_vars_1), (None, dict_vars_2)]

    pool = threadpool.ThreadPool(2)
    requests = threadpool.makeRequests(hello, func_var)
    [pool.putRequest(req) for req in requests]
    pool.wait()

#输出
m = 1  n=2  o=3
m = 4  n=5  o=6
[Finished in 2.3s]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值