匠心精神 - 良心品质腾讯认可的专业机构-IT人的高薪实战学院

咨询电话:4000806560

【实用】Python中的并发编程及应用

【实用】Python中的并发编程及应用

随着计算机处理器性能的提高,我们的代码执行速度也得到了极大的提升。但是,随着数据量的不断增加以及业务的不断扩展,传统的单线程编程方式已经不能满足我们的需求。因此,我们需要一种更为高效的编程方式,那就是并发编程。

Python 是一门十分适合并发编程的语言。它提供了丰富的内置库和第三方库,可以让程序员轻松地实现并发编程。在本文中,我们将介绍 Python 中的并发编程以及如何应用它们。

一、并发编程的概念

并发编程是指在程序中同时执行多个任务的编程方式。举个例子,假设我们需要下载多个文件。传统的单线程编程方式可能需要依次下载每个文件,这样会大大降低程序的效率。而使用并发编程,我们可以同时下载多个文件,极大提高程序的效率。

但是并发编程的实现可以有多种方式,比如多线程、多进程、协程等。在 Python 中,除了使用多线程和多进程之外,还可以使用协程来实现并发编程。

二、多线程

多线程是一种常用的并发编程方式,可以让程序同时执行多个任务,从而提高程序的效率。在 Python 中实现多线程需要使用 threading 库。

下面是一个简单的例子:

```python
import threading

def print_numbers():
    for i in range(10):
        print(i)

def print_letters():
    for i in range(10):
        print(chr(ord('a')+i))

if __name__ == '__main__':
    t1 = threading.Thread(target=print_numbers)
    t2 = threading.Thread(target=print_letters)

    t1.start()
    t2.start()
```

在这个例子中,我们定义了两个函数分别用来打印数字和字母。然后使用 threading.Thread() 函数创建了两个线程,并将这两个函数作为参数传递进去。最后调用 start() 方法来启动线程。

需要注意的是,当我们运行这个程序的时候,可能会出现数字和字母打印混乱的情况。这是因为多线程是同时执行的,它们之间的执行顺序是无法保证的。

三、多进程

多进程也是一种常用的并发编程方式,可以让程序同时执行多个任务,从而提高程序的效率。在 Python 中实现多进程需要使用 multiprocessing 库。

下面是一个简单的例子:

```python
import multiprocessing

def print_numbers():
    for i in range(10):
        print(i)

def print_letters():
    for i in range(10):
        print(chr(ord('a')+i))

if __name__ == '__main__':
    p1 = multiprocessing.Process(target=print_numbers)
    p2 = multiprocessing.Process(target=print_letters)

    p1.start()
    p2.start()
```

在这个例子中,我们同样定义了两个函数分别用来打印数字和字母。然后使用 multiprocessing.Process() 函数创建了两个进程,并将这两个函数作为参数传递进去。最后调用 start() 方法来启动进程。

需要注意的是,多进程需要考虑到进程间通信的问题,比如使用 Queue 或者 Pipe 等方式来实现进程间通信。

四、协程

协程是一种轻量级的并发编程方式,可以轻松地实现大量的并发任务。在 Python 中实现协程需要使用 asyncio 库。

下面是一个简单的例子:

```python
import asyncio

async def print_numbers():
    for i in range(10):
        print(i)
        await asyncio.sleep(0.1)

async def print_letters():
    for i in range(10):
        print(chr(ord('a')+i))
        await asyncio.sleep(0.1)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(print_numbers(), print_letters()))
```

在这个例子中,我们定义了两个协程函数分别用来打印数字和字母。然后使用 asyncio.gather() 函数来将这两个协程函数一起运行。

需要注意的是,协程需要使用 async 和 await 关键字来定义和调用协程函数。

五、应用实例

下面我们来介绍一下如何使用并发编程来实现常见的应用场景。

1. 爬虫

爬虫是一种常见的并发场景,可以使用多线程或者协程来提高爬虫的效率。下面是一个使用多线程实现的简单爬虫:

```python
import requests
import threading
from queue import Queue

url_list = [
    'http://www.baidu.com',
    'http://www.qq.com',
    'http://www.sina.com',
    'http://www.taobao.com',
]

def get_url(q):
    while not q.empty():
        url = q.get()
        r = requests.get(url)
        print(url, len(r.text))

def main():
    q = Queue()
    for url in url_list:
        q.put(url)

    thread_list = []
    for i in range(5):
        t = threading.Thread(target=get_url, args=(q,))
        t.start()
        thread_list.append(t)

    for t in thread_list:
        t.join()

if __name__ == '__main__':
    main()
```

在这个例子中,我们定义了一个函数 get_url() 来获取网页内容。然后使用 Queue 来存储需要爬取的网址。使用多线程来同时访问多个网址。需要注意的是,在实际开发中需要添加一些限制条件来防止被封 IP。

2. 数据处理

数据处理是一种常见的并发场景,可以使用多进程或者协程来提高数据处理的效率。下面是一个使用多进程实现的简单数据处理程序:

```python
import multiprocessing

data_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def square(data):
    return data*data

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=4)
    results = []

    for data in data_list:
        result = pool.apply_async(square, args=(data,))
        results.append(result)

    pool.close()
    pool.join()

    for result in results:
        print(result.get())
```

在这个例子中,我们定义了一个函数 square() 来计算数据的平方。然后使用 multiprocessing.Pool() 函数来创建进程池。将数据进行分组,并且使用 apply_async() 方法来异步计算。最后使用 get() 方法获取数据计算结果。

需要注意的是,在实际开发中需要考虑到进程间通信和数据分布的问题。

3. 实时数据处理

实时数据处理是一种常见的并发场景,可以使用协程来提高实时数据处理的效率。下面是一个使用协程实现实时数据处理程序:

```python
import asyncio

async def read_data():
    while True:
        data = await read_sensor()
        await process_data(data)
        
async def read_sensor():
    # 从传感器读取数据
    pass

async def process_data(data):
    # 处理数据
    pass

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(read_data())
```

在这个例子中,我们定义了两个协程函数 read_sensor() 和 process_data(),分别用来读取传感器数据和处理数据。使用 asyncio.get_event_loop() 函数来创建事件循环,然后使用 run_until_complete() 方法来运行协程函数 read_data()。

需要注意的是,在实际开发中协程的执行顺序是无法保证的,这需要根据具体的业务需求进行调整。

六、总结

并发编程是一种提高程序效率的重要方式。在 Python 中,可以使用多线程、多进程、协程等方式实现并发编程。需要根据不同的业务需求选择合适的并发编程方式。同时,需要注意到并发编程也会带来一些问题,如竞态条件、锁问题等,需要谨慎处理。