Python多线程与多进程及其区别(2)

import threading import time def tstart(arg): print("%s running....at: %s" % (arg,time.time())) time.sleep(1) print("%s is finished! at: %s" % (arg,time.time())) if __name__ == '__main__': t1 = threading.Thread(target=tstart, args=('This is thread 1',)) t1.setDaemon(True) t1.start() # t1.join() # 当前线程阻塞,等待t1线程执行完成 print("This is main function at:%s" % time.time())

结果:

This is thread 1 running....at: 1564906847.85 This is main function at:1564906847.85

python多进程

相比较于threading模块用于创建python多线程,python提供multiprocessing用于创建多进程。先看一下创建进程的两种方式。

The multiprocessing package mostly replicates the API of the threading module.  —— python doc

创建进程

创建进程的方式和创建线程的方式类似:

实例化一个multiprocessing.Process的对象,并传入一个初始化函数对象(initial function )作为新建进程执行入口;

继承multiprocessing.Process,并重写run函数;

方式1:

from multiprocessing import Process import os, time def pstart(name): # time.sleep(0.1) print("Process name: %s, pid: %s "%(name, os.getpid())) if __name__ == "__main__": subproc = Process(target=pstart, args=('subprocess',)) subproc.start() subproc.join() print("subprocess pid: %s"%subproc.pid) print("current process pid: %s" % os.getpid())

结果:

Process name: subprocess, pid: 4888 subprocess pid: 4888 current process pid: 9912

方式2:

from multiprocessing import Process import os, time class CustomProcess(Process): def __init__(self, p_name, target=None): # step 1: call base __init__ function() super(CustomProcess, self).__init__(name=p_name, target=target, args=(p_name,)) def run(self): # step 2: # time.sleep(0.1) print("Custom Process name: %s, pid: %s "%(self.name, os.getpid())) if __name__ == '__main__': p1 = CustomProcess("process_1") p1.start() p1.join() print("subprocess pid: %s"%p1.pid) print("current process pid: %s" % os.getpid())

这里可以思考一下,如果像多线程一样,存在一个全局的变量share_data,不同进程同时访问share_data会有问题吗?

由于每一个进程拥有独立的内存地址空间且互相隔离,因此不同进程看到的share_data是不同的、分别位于不同的地址空间,同时访问不会有问题。这里需要注意一下。

Subprocess模块

既然说道了多进程,那就顺便提一下另一种创建进程的方式。

python提供了Sunprocess模块可以在程序执行过程中,调用外部的程序。

如我们可以在python程序中打开记事本,打开cmd,或者在某个时间点关机:

>>> import subprocess >>> subprocess.Popen(['cmd']) <subprocess.Popen object at 0x0339F550> >>> subprocess.Popen(['notepad']) <subprocess.Popen object at 0x03262B70> >>> subprocess.Popen(['shutdown', '-p'])

或者使用ping测试一下网络连通性:

>>> res = subprocess.Popen(['ping', 'www.cnblogs.com'], stdout=subprocess.PIPE).communicate()[0] >>> print res 正在 Ping [101.37.113.127] 具有 32 字节的数据:

来自 101.37.113.127 的回复: 字节=32 时间=1ms TTL=91
来自 101.37.113.127 的回复: 字节=32 时间=1ms TTL=91
来自 101.37.113.127 的回复: 字节=32 时间=1ms TTL=91
来自 101.37.113.127 的回复: 字节=32 时间=1ms TTL=91

101.37.113.127 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 1ms,最长 = 1ms,平均 = 1ms

python多线程与多进程比较

先来看两个例子:

开启两个python线程分别做一亿次加一操作,和单独使用一个线程做一亿次加一操作:

def tstart(arg): var = 0 for i in xrange(100000000): var += 1 if __name__ == '__main__': t1 = threading.Thread(target=tstart, args=('This is thread 1',)) t2 = threading.Thread(target=tstart, args=('This is thread 2',)) start_time = time.time() t1.start() t2.start() t1.join() t2.join() print("Two thread cost time: %s" % (time.time() - start_time)) start_time = time.time() tstart("This is thread 0") print("Main thread cost time: %s" % (time.time() - start_time))

结果:

Two thread cost time: 20.6570000648 Main thread cost time: 2.52800011635

上面的例子如果只开启t1和t2两个线程中的一个,那么运行时间和主线程基本一致。这个后面会解释原因。

使用两个进程进行上面的操作:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8abfe932db5ef9cdd61f376dbdc00883.html