多进程 Process
def run_something(name):
print("这里使用 %s进程 处理 %s." % (os.getpid(), name))
if __name__ == '__main__':
print("当前进程是: %s" % os.getpid())
pro = Process(target=run_something, args=('Hello',))
pro.start()
pro.join()
print("子进程结束.")
运行结果:
当前进程是: 9304
这里使用 9309进程 处理 Hello.
子进程结束.
子进程 subprocess
示例:
if __name__ == '__main__':
print("$nslookup www.so.com:")
sre = subprocess.call(['nslookup', 'www.so.com'])
print("Exit ", sre)
运行结果:
$nslookup www.so.com:
Server: 127.0.1.1
Address: 127.0.1.1#53
Non-authoritative answer:
www.so.com canonical name = so.qh-lb.com.
Name: so.qh-lb.com
Address: 125.88.193.243
Exit 0
进程通信 Queue
示例:
# python 2.x
from Queue import Queue
def os_write(qu):
print("当前 write 进程是: %s" % os.getpid())
for i in range(5):
print("通道装载数据: %d" % i)
qu.put(i)
time.sleep(random.random() * 2)
def os_read(qu):
print("当前 read 进程是: %s" % os.getpid())
while True:
print("从通道中获取: ", qu.get(True))
if __name__ == '__main__':
qu = Queue()
pw = Process(target=os_write, args=(qu,))
pr = Process(target=os_read, args=(qu,))
pw.start()
pr.start()
pw.join()
if qu.empty():
pr.terminate()
print("进程结束")
运行结果:
当前 write 进程是: 12670
通道装载数据: 0
当前 read 进程是: 12671
从通道中获取: 0
通道装载数据: 1
从通道中获取: 1
通道装载数据: 2
从通道中获取: 2
通道装载数据: 3
从通道中获取: 3
通道装载数据: 4
从通道中获取: 4
进程结束
多线程 Thread
# 导入Python标准库中的Thread模块
from threading import Thread
def run_loop():
print("当前线程是: %s" % threading.current_thread().name)
for i in range(6):
print("线程 %s 处理 %d" % (threading.current_thread().name, i))
time.sleep(random.random() * 2)
print("线程 %s 结束." % threading.current_thread().name)
if __name__ == '__main__':
print("当前线程是: %s" % threading.current_thread().name)
# 创建一个线程
td = Thread(target=run_loop, name="LoopThread")
# 启动 刚创建的线程
td.start()
# 线程 等待 ( 等待子线程都执行完毕了,主线程再关闭 )
td.join()
print("线程 %s 结束." % threading.current_thread().name)
运行结果:
当前线程是: MainThread
当前线程是: LoopThread
线程 LoopThread 处理 0
线程 LoopThread 处理 1
线程 LoopThread 处理 2
线程 LoopThread 处理 3
线程 LoopThread 处理 4
线程 LoopThread 处理 5
线程 LoopThread 结束.
线程 MainThread 结束.
多线程与多进程的区别 ^1
多线程 和 多进程 最大的不同在于, 多进程 中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享
使用继承类创建 ^2
from threading import Thread
# 创建一个类,必须要继承Thread
class MyThread(Thread):
# 继承Thread的类,需要实现run方法,线程就是从这个方法开始的
def run(self):
# 具体的逻辑
function_name(self.parameter1)
def __init__(self, parameter1):
# 需要执行父类的初始化方法
Thread.__init__(self)
# 设置守护线程
self.setDaemon(True)
# 如果有参数,可以封装在类里面
self.parameter1 = parameter1
# 如果有参数,实例化的时候需要把参数传递过去
t = MyThread(parameter1)
# 同样使用start()来启动线程
t.start()
在__init__中,self实际上就是Thread类的对象,所以
setDaemon
实际上是Thread类的一个方法,当设置为True就可以把当前类变成一个守护线程,等到其他线程都停止以后,它会自动停止。
线程事件通知 ^2
from threading import Event, Thread
# 接收一个Event对象
def test_event(e):
print('run...')
# 让这个线程进入睡眠状态
e.wait()
# 当线程被唤醒以后,会输出下面的语句
print('end...')
e = Event()
t = Thread(target=test_event, args=(e,))
# 这里会看到输出了 run...
t.start()
print('Set Event...')
# 唤醒线程会看到 end...
e.set()
注意:当我们程序在一起运行周期内,重复调用
e.wait()
,第二次调用就无法让线程进入休眠状态了,需要调用e.clear()
清除以后,才能再次进入休眠状态。
创建线程本地数据 ^2
import threading
L = threading.local()
L.num = 1
# 此时操作的是我们当前主线程的threading.local()对象,输出结果为1
print(L.num)
def f():
L.num = 5
# 这里可以成功的输出5
print(L.num)
# 创建一个子线程,去调用f(),看能否访问主线程中定义的L.num
t = threading.Thread(target=f)
t.start()
# 主线程中的L.num依然是1,没有发生任何改变
print(L.num)
threading.local()创建的对象中的属性,是对于每个线程独立存在的,它们相互之间无法干扰。