python并发编程

一、进程

        Python进程是操作系统中执行的独立的任务实体,每个进程都有自己的地址空间和系统资源(进程之间相互隔离,不能共享进程变量)。Python的多进程模块multiprocessing可以用来创建和管理进程。每个进程都可以独立执行,拥有自己的全局变量和代码执行流程。进程之间通过进程间通信(IPC)来进行数据交换。

常用方法

1.创建进程:可以使用Process类来创建进程。首先导入multiprocessing模块,然后通过Process类的构造函数创建一个进程对象。

from multiprocessing import Process

def func():
    print("Hello, World!")

if __name__ == "__main__":
    p = Process(target=func)
    p.start()
    p.join()

        上面的例子使用了target关键字指定了进程对应的函数,在 Process 类中,除了 target 参数,还有一些其他可用的参数可以用来控制子进程的行为。以下是一些常用的参数:

  • args:一个元组,用于传递给 target 函数的位置参数。
  • kwargs:一个字典,用于传递给 target 函数的关键字参数。
  • name:一个字符串,用于设置子进程的名称。
  • daemon:一个布尔值,用于设置子进程是否为守护进程。
  • group:一个 Group 对象,用于将子进程添加到指定的进程组。

 2.进程间通信:不同进程之间无法直接共享内存,需要使用特定的机制进行进程间通信。multiprocessing模块提供了QueuePipe等用于进程间通信的类。例如,使用Queue实现进程间的消息传递:

from multiprocessing import Process, Queue

def func(q):
    q.put("Hello, World!")

if __name__ == "__main__":
    q = Queue()
    p = Process(target=func, args=(q,))
    p.start()
    print(q.get())
    p.join()

3.进程池:如果需要同时执行多个进程,可以使用进程池来管理进程。multiprocessing模块提供了Pool类来实现进程池。例如,使用进程池并行执行多个任务:

from multiprocessing import Pool

def func(x):
    return x * x

if __name__ == "__main__":
    with Pool(processes=4) as pool:
        result = pool.map(func, range(10))
        print(result)

4.共享内存:虽然不同进程之间无法直接共享内存,但可以使用ValueArray等类来创建共享内存。例如,使用Value创建一个共享的整数:

from multiprocessing import Process, Value

def func(n):
    n.value += 1

if __name__ == "__main__":
    n = Value('i', 0)
    p1 = Process(target=func, args=(n,))
    p2 = Process(target=func, args=(n,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print(n.value)

进程特点

  1. 独立性:每个进程都是一个独立的实体,有自己独立的内存空间和系统资源。进程之间相互隔离,一个进程的错误不会影响其他进程的运行。

  2. 并发性:多个进程可以同时执行,每个进程都有自己的执行流。操作系统通过时间片轮转等调度算法来切换进程的执行,使得进程看起来是同时运行的。

  3. 隔离性:不同进程之间的内存空间是隔离的,一个进程无法直接访问另一个进程的内存。进程之间的通信需要通过特定的机制,如管道、消息队列等。

  4. 共享性:虽然进程之间的内存是隔离的,但可以通过特定的机制实现进程间的数据共享。例如,使用共享内存、文件等来实现进程间的数据交换。

  5. 系统开销:每个进程都需要占用一定的系统资源,如内存、CPU时间等。创建和销毁进程都需要一定的开销,因此过多的进程会增加系统的负担。

  6. 安全性:由于进程之间的隔离性,进程之间的数据不会相互干扰。这提高了系统的安全性,一个进程的错误不会对其他进程造成影响。

二、线程

        Python线程是Python中用于实现并发编程的一种机制。线程是进程内的执行单元,一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间、文件描述符等。与进程相比,线程的创建和切换开销较小,可以更加高效地实现并发操作。

创建线程:可以通过继承threading.Thread类或使用threading.Thread类的构造函数来创建线程。例如:

import threading

# 继承Thread类创建线程
class MyThread(threading.Thread):
    def run(self):
        # 线程执行的代码
        print("Hello, I'm a thread!")

# 使用Thread类的构造函数创建线程
thread = threading.Thread(target=func)

启动线程:通过调用线程对象的start()方法来启动线程。启动线程后,线程会自动调用run()方法来执行线程的代码。

thread.start()

 线程同步:由于多个线程共享进程的资源,可能会导致资源竞争和数据不一致的问题。可以使用锁(Lock)来保证线程间的同步。例如:

import threading

# 创建锁对象
lock = threading.Lock()

# 在需要同步的代码块中使用锁
lock.acquire()
# 临界区代码
lock.release()

 线程间通信:线程间可以通过共享变量来进行通信。为了避免数据竞争,可以使用Queue等线程安全的数据结构来实现线程间的数据传递。

import threading
from queue import Queue

# 创建队列对象
queue = Queue()

# 在生产者线程中向队列中放入数据
queue.put(data)

# 在消费者线程中从队列中取出数据
data = queue.get()

 线程状态:线程可以处于就绪、运行、阻塞等不同的状态。可以通过threading.Thread类的is_alive()方法来判断线程是否在运行。

thread.is_alive()  # 判断线程是否在运行

三、协程

        协程是一种用户级线程,也被称为轻量级线程。协程在同一个线程中执行,共享同一个地址空间和系统资源。协程可以在执行过程中主动让出CPU,并保存当前执行的上下文,以便后续重新恢复执行。Python的协程模块asyncio提供了一种基于事件循环的协程编程模型。协程之间通过awaitasync关键字来进行协作和数据交换。

        在Python中,可以使用threading模块来创建和管理线程。下面是一些常用的线程操作:

1、创建线程:可以通过继承threading.Thread类或使用threading.Thread类的构造函数来创建线程。例如:

import threading

# 继承Thread类创建线程
class MyThread(threading.Thread):
    def run(self):
        # 线程执行的代码
        print("Hello, I'm a thread!")

# 使用Thread类的构造函数创建线程
thread = threading.Thread(target=func)

2、启动线程:通过调用线程对象的start()方法来启动线程。启动线程后,线程会自动调用run()方法来执行线程的代码。

thread.start()

3、线程同步:由于多个线程共享进程的资源,可能会导致资源竞争和数据不一致的问题。可以使用锁(Lock)来保证线程间的同步。例如:

import threading

# 创建锁对象
lock = threading.Lock()

# 在需要同步的代码块中使用锁
lock.acquire()
# 临界区代码
lock.release()

4、线程间通信:线程间可以通过共享变量来进行通信。为了避免数据竞争,可以使用Queue等线程安全的数据结构来实现线程间的数据传递。

import threading
from queue import Queue

# 创建队列对象
queue = Queue()

# 在生产者线程中向队列中放入数据
queue.put(data)

# 在消费者线程中从队列中取出数据
data = queue.get()

5、线程状态:线程可以处于就绪、运行、阻塞等不同的状态。可以通过threading.Thread类的is_alive()方法来判断线程是否在运行。

thread.is_alive()  # 判断线程是否在运行

四、异步编程

异步编程是一种编程模式,用于处理并发和并行的任务。在传统的同步编程中,代码按照顺序依次执行,每个操作都会阻塞代码的执行,直到操作完成才能继续执行下一个操作。而在异步编程中,代码可以在等待某个操作完成的同时继续执行其他操作,从而提高程序的并发性和响应能力。

异步编程的核心概念是协程(coroutine)和事件循环(event loop)。(涉及到asyncio 库,我也不太懂

协程

协程是一种特殊的函数,它可以在执行过程中暂停并保存当前的状态,然后可以在需要的时候恢复执行。在Python中,协程是通过生成器实现的。然而协程与生成器的概念并不相同,协程消费数据,生成器生成数据 ,同时协程与迭代无关

我们可以使用async和await关键字来定义和管理协程 ,async作为协程关键字,放在协程函数前,await关键字用于暂停协程执行,等待一个异步操作的结果。

示例:

import asyncio

async def my_coroutine():
    print("协程开始")
    await asyncio.sleep(1)
    print("协程结束")

上述代码中使用了async关键字生成了一个名为my_coroutine的协程函数,它会打印出“协程开始”然后通过 await asyncio.sleep(1)暂停协程1秒钟,最后打印出“协程结束”。

事件循环

        事件循环是异步编程的核心机制,它负责调度和执行协程。事件循环会不断地从任务队列中取出协程,执行一段时间,然后再切换到其他的协程。与GUI不同的是asyncio库写出的事件队列需要手动维护。

事件循环的工作流程如下:(目前我不会用所以给不出例子

  1. 创建事件循环对象:使用asyncio.get_event_loop()函数获取默认的事件循环对象,或者使用asyncio.new_event_loop()函数创建一个新的事件循环对象。

  2. 将协程添加到事件循环中:使用loop.run_until_complete()方法将一个协程添加到事件循环中,使其开始执行。事件循环会一直执行,直到协程完成。

  3. 执行协程:事件循环会不断地从任务队列中取出协程,并执行一段时间。当协程需要等待某个操作完成时,事件循环会将控制权交还给操作系统,然后继续执行其他的协程。

  4. 等待操作完成:当协程需要等待某个操作完成时,可以使用await关键字将控制权交还给事件循环。事件循环会等待操作完成,并在操作完成后再次调度该协程继续执行。

  5. 停止事件循环:可以使用loop.stop()方法停止事件循环的执行。也可以使用loop.run_forever()方法使事件循环一直执行,直到调用loop.stop()方法停止。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值