Python 并行编程

本文介绍了Python中的并行编程,包括使用线程和进程。详细讲解了线程的创建与同步,如Thread类、args参数、线程同步的锁(Lock和RLock)、Event的wait和set方法。同时提到了进程的multiprocessing模块,如process、join、pool和进程间通信的Queue与Pipe。

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

execvp开启一个新的进程,替换当前的进程,当前进程不再运行
execl(file, arg0,arg1,…) 用参数列表arg0, arg1 等等执行文件
execlp(cmd, arg0,arg1,…) 于execl()相同,但是在用户的搜索路径下搜索完全的文件路径名
execvp(cmd, arglist) 除了带有参数向量列表,与execlp()相同

os.execl("/usr/bin/python ", "python ", 'test.py ', 'i ') 

python的sys.argv应是c中argv的[1:],所以os.execl中的第二个参数 "python "对于python程序test.py不可见而且没有用。
实际上os.execl的第二个参数也就是int main(int argc,char** argv)中的argv[0]可以是任意的,它本质上是提供给c程序作为main()函数的第一个参数使用。

基于线程的并行是编写并行程序的标准方法。然而Python解释器并不完全是线程安全,GIL并没有完全解决线程安全的问题

使用线程最简单的方式是用一个目标函数实例化一个Thread然后调用start()方法启动它。Python的threading模块提供了Thread()方法在不同的线程中运行函数或处理过程等。

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})

  • group:特性预留
  • target:当线程启动的时候要执行的函数
  • name:线程的名字,默认为Thread-N
  • args:传递给target的参数,要试用tuple类型
  • kwargs:同上,试用字段类型dict
t = threading.Thread(target=function, args=(i,))
threads.append(t)
t.start()
t.join()

t.join:主线程会调用t线程,然后等待t线程完成再执行for循环开启下一个t线程。可理解为阻塞主线程。

确定线程
可自定义名字

t1 = threading.Thread(name='first_function', target=first_function)
t2 = threading.Thread(name='second_function', target=second_function)
t3 = threading.Thread(name='third_function', target=third_function)

用锁解决同步问题lock

shared_resource_with_lock = 0
shared_resource_with_no_lock = 0
count = 100000

shared_resource_lock = threading.Lock()

# has lock
def increment_with_lock():
    global shared_resource_with_lock
    for i in range(count):
        shared_resource_lock.acquire()
        shared_resource_with_lock += 1
        shared_resource_lock.release()

acquire() and release()

线程同步RLock

如果想让只有拿到锁的线程才能释放该锁,那么应该使用RLock()对象。当需要在类外面保证线程安全,又要在类内使用同样方法的时候RLock()就很使用。

RLock叫做Reentrant Lock,就是可以重复进入的锁,也叫递归锁。这种锁对比Lock有三个特点:1、谁拿到锁,谁释放;2、同一线程可以多次拿到该锁;3、acquire多少次就必须release多少次,只有最后一次release才能改变RLock的状态为unlocked。

lock = threading.RLock()

Event中wait和set

# coding : utf-8

import time
from threading import Thread, Event
import random

items = []
event = Event()

class consumer(Thread):
    def __init__(self, items, event):
        Thread.__init__(self)
        self.items = items
        self.event = event

    def run(self):
        while True:
            time.sleep(2)
            print("Cosumer is waiting...")
            self.event.wait()
            item = self.items.pop()
            print("Consumer notify: %d popped from list by %s" %(item, self.name))

class producer(Thread):
    def __init__(self, integers, event):
        Thread.__init__(self)
        self.items = items
        self.event = event

    def run(self):
        global item
        for i in range(100):
            time.sleep(2)
            item = random.randint(0, 256)
            self.items.append(item)
            print('Producer notify : item N° %d appended to list by %s' % (item, self.name))
            print('Producer notify : event set by %s' % self.name)
            self.event.set()
            print('Produce notify : event cleared by %s '% self.name)
            self.event.clear()
if __name__ == '__main__':
    t1 = producer(items, event)
    t2 = consumer(items, event)
    t2.start()
    t1.start()
    t2.join()
    t1.join()

基本上事件对象都会维护一个内部变量,可以通过set方法设置为true,也可以通过clear方法设置为false。wait方法将会阻塞线程,直到内部变量为true。

multiprocessing process 创建子进程,与Threading类似
join([超时])

pool 提供指定数量的进程供用户调用,
pool.apply_async()异步进程池

multiprocessing的Queue和Pipe 进行进程间的通信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值