赞
踩
并发编程是指计算机系统中同时执行多个独立的计算任务。这些任务可以同时执行也可以按照一定的调度策略交替执行。在并发编程中执行的任务需要独立管理自身的资源,且需要与其他任务共享资源。
在现代计算机系统中单个CPU的处理速度已经很快了。然而现代应用程序通常需要处理大量的任务和数据,单个CPU无法满足这些需求。因此需要使用多个线程或进程并发处理这些任务和数据,以提高应用程序的执行效率和响应速度。
虽然并发编程可以提高程序执行效率,但同时也带来了一些挑战:
Python提供了threading
模块用于创建和管理多个线程。以下是一个简单的例子:
import threading def worker(): """Thread worker function""" print('This is a thread') # Create threads thread1 = threading.Thread(target=worker) thread2 = threading.Thread(target=worker) # Start threads thread1.start() thread2.start() # Wait for threads to finish thread1.join() thread2.join()
上述代码创建了两个线程分别执行worker()
函数。使用start()
函数启动线程,使用join()
函数等待线程执行完毕。
Python提供了multiprocessing
模块可以在多个进程中并发运行Python代码。以下是一个简单的例子:
import multiprocessing def worker(): """Process worker function""" print('This is a process') # Create processes process1 = multiprocessing.Process(target=worker) process2 = multiprocessing.Process(target=worker) # Start processes process1.start() process2.start() # Wait for processes to finish process1.join() process2.join()
上述代码创建了两个进程分别执行worker()
函数。使用start()
函数启动进程,使用join()
函数等待进程执行完毕。
Python提供了asyncio
库可以通过协程和异步IO编程实现高效的并发处理。以下是一个简单的例子:
import asyncio
async def worker():
"""Asyncio worker function"""
print('This is a coroutine')
# Create event loop
loop = asyncio.get_event_loop()
# Create tasks
task1 = loop.create_task(worker())
task2 = loop.create_task(worker())
# Wait for tasks to finish
loop.run_until_complete(asyncio.gather(task1, task2))
上述代码创建了两个协程使用create_task()
函数将其转换为任务。使用run_until_complete()
函数等待任务执行完毕。
在现代计算机系统中单个CPU的处理速度已经很快了。然而现代应用程序通常需要处理大量的任务和数据,单个CPU无法满足这些需求。因此使用多个线程并发处理这些任务和数据,以提高应用程序的执行效率和响应速度。接下来将介绍Python中的多线程编程实践。
Python中创建线程非常简单只需使用threading
模块即可。以下是一个简单的例子:
import threading
# 定义线程执行的函数
def worker():
print('This is a thread')
# 创建线程
thread = threading.Thread(target=worker)
# 启动线程
thread.start()
# 等待线程执行完毕
thread.join()
上述代码创建了一个线程使用start()
函数启动它,使用join()
函数等待线程执行完毕。
线程的生命周期包括以下几个阶段:
在多线程编程中可能会涉及共享资源的访问问题,如果多个线程同时访问同一个共享资源,会导致数据竞争和错误的结果。因此需要使用线程同步和互斥机制。
Lock是一种简单的互斥机制用于保护共享资源的访问。以下是一个简单的例子:
import threading # 定义共享变量 count = 0 # 定义锁 lock = threading.Lock() # 定义计数函数 def counter(): global count for i in range(1000000): lock.acquire() count += 1 lock.release() # 创建线程 thread1 = threading.Thread(target=counter) thread2 = threading.Thread(target=counter) # 启动线程 thread1.start() thread2.start() # 等待线程执行完毕 thread1.join() thread2.join() # 输出计数结果 print(count)
上述代码使用Lock保护共享变量的访问,确保每个线程都可以正确地访问和修改共享变量。
RLock是一种可重入的互斥机制,允许同一个线程对同一个锁进行多次加锁和解锁。以下是一个简单的例子:
import threading # 定义共享变量 count = 0 # 定义锁 lock = threading.RLock() # 定义计数函数 def counter(): global count for i in range(1000000): lock.acquire() lock.acquire() # 多次加锁 count += 1 lock.release() lock.release() # 多次解锁 # 创建线程 thread1 = threading.Thread(target=counter) thread2 = threading.Thread(target=counter) # 启动线程 thread1.start() thread2.start() # 等待线程执行完毕 thread1.join() thread2.join() # 输出计数结果 print(count)
上述代码使用RLock保护共享变量的访问,允许同一个线程对同一个锁进行多次加锁和解锁。
在多线程编程中可能需要线程之间进行通信,以共享数据或进行协作。Python提供了多种方式来实现线程之间的通信。
队列是一种线程安全的数据结构可以用来进行线程之间的通信。以下是一个简单的例子:
import threading import queue # 定义队列 q = queue.Queue() # 定义生产者函数 def producer(): for i in range(10): q.put(i) print('生产者生产了', i) # 定义消费者函数 def consumer(): while True: item = q.get() if item is None: break print('消费者消费了', item) # 创建线程 thread1 = threading.Thread(target=producer) thread2 = threading.Thread(target=consumer) # 启动线程 thread1.start() thread2.start() # 等待生产者线程执行完毕 thread1.join() # 将None添加到队列中,通知消费者线程结束 q.put(None) # 等待消费者线程执行完毕 thread2.join()
上述代码使用队列实现了生产者-消费者模式,实现了线程之间的通信。
线程池是一种常见的优化多线程程序的方式,可以有效地复用线程,避免频繁地创建和销毁线程。Python提供了concurrent.futures
模块,可以很容易地创建和管理线程池。以下是一个简单的例子:
import concurrent.futures import time # 定义任务函数 def worker(i): print('Thread', i, 'start') time.sleep(1) print('Thread', i, 'end') # 创建线程池 with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor: # 提交任务 futures = [executor.submit(worker, i) for i in range(10)] # 等待任务完成 for future in concurrent.futures.as_completed(futures): result = future.result()
上述代码创建了一个包含3个线程的线程池,提交了10个任务。使用as_completed()
函数等待任务执行完毕。
除了常规的线程池外,Python还提供了使用队列实现的线程池,可以更好地控制任务的执行方式。以下是一个简单的例子:
import concurrent.futures import time import queue # 定义任务函数 def worker(i, q): print('Thread', i, 'start') item = q.get() time.sleep(1) print('Thread', i, 'finish', item) q.task_done() # 定义任务队列 q = queue.Queue() # 向队列中添加任务 for i in range(10): q.put(i) # 创建线程池 with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor: # 提交任务 futures = [executor.submit(worker, i, q) for i in range(3)] # 等待任务完成 q.join() # 取消未执行的任务 for future in futures: future.cancel()
上述代码使用队列实现了线程池,对于每个任务,只有一个线程可以执行,避免了竞争的情况。使用队列的join()
函数等待所有任务完成。未执行的任务可以使用cancel()
函数取消。
下面将介绍Python中的协程与异步IO编程实践
协程是一种轻量级的线程可以在单个线程内部实现并发执行。协程能够在不同的执行点之间暂停和继续执行,类似于线程的上下文切换。协程的优点在于避免了线程的创建和上下文切换开销,同时也避免了多线程程序中可能存在的数据竞争和锁问题。
Python的协程通过生成器实现使用yield
语句来暂停和恢复协程的执行。以下是一个简单的例子:
# 定义协程函数 def coroutine(): print('Coroutine start') while True: value = yield print('Coroutine received:', value) # 创建协程对象 coro = coroutine() # 启动协程 next(coro) # 向协程发送数据 coro.send('data1') coro.send('data2')
上述代码创建了一个协程对象,使用yield
语句来暂停和恢复协程的执行。使用next()
函数启动协程,使用send()
函数向协程发送数据。
Python提供了asyncio
模块可以很容易地进行协程和异步IO编程。asyncio
提供了一个事件循环(Event Loop
),可以在单线程中实现异步的协程调度和IO操作。
以下是一个简单的例子展示了如何创建和启动一个协程,以及如何使用事件循环:
import asyncio # 定义协程函数 async def coroutine(): print('Coroutine start') await asyncio.sleep(1) print('Coroutine end') # 创建事件循环 loop = asyncio.get_event_loop() # 启动协程 loop.run_until_complete(coroutine()) # 关闭事件循环 loop.close()
上述代码中使用async
关键字定义了一个协程函数,使用await
关键字来暂停和恢复协程的执行。使用asyncio.get_event_loop()
函数创建事件循环,使用loop.run_until_complete()
函数启动协程,并等待协程执行结束。最后使用loop.close()
函数关闭事件循环。
asyncio
可以很容易地实现多个协程的并发执行。以下是一个简单的例子:
import asyncio # 定义协程函数 async def coroutine(i): print('Coroutine', i, 'start') await asyncio.sleep(1) print('Coroutine', i, 'end') # 创建事件循环 loop = asyncio.get_event_loop() # 启动多个协程 coros = [coroutine(i) for i in range(5)] loop.run_until_complete(asyncio.gather(*coros)) # 关闭事件循环 loop.close()
上述代码创建了多个协程对象使用asyncio.gather()
函数启动这些协程,并等待它们执行完毕。使用*coros
语法将协程列表解包为单独的参数。
除了协程的并发执行外,asyncio
还提供了异步IO操作的实现,以提高应用程序的执行效率和响应速度。以下是一个简单的例子,展示了如何使用异步IO进行文件的读取和写入:
import asyncio # 定义异步IO操作函数 async def file_io(): # 打开文件 with open('test.txt', 'r') as f1, open('output.txt', 'w') as f2: # 读取文件 data = await f1.read() # 写入文件 await f2.write(data) # 创建事件循环 loop = asyncio.get_event_loop() # 启动异步IO操作 loop.run_until_complete(file_io()) # 关闭事件循环 loop.close()
上述代码使用async with
语法打开文件,并使用await
关键字进行异步IO操作。在文件读取和写入操作之间使用await asyncio.sleep()
函数来模拟IO操作的延迟。
除此之外asyncio
还提供了许多其他的异步IO操作,如TCP连接、UDP连接、HTTP请求等可以根据需要进行选择和使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。