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 进行进程间的通信