前言
进程是操作系统的中执行的程序,操作系统以进程为单位分配存储系统,每个进程都有自己的地址空间、数据栈以及其他用于跟踪进程的辅助数据,操作系统管理所有进程的执行,为它们分配合理的资源。由于进程是一个独立的内存空间,所以他们之间必须通过进程间通信机制(IPC,Inter-Process Communication)来实现数据共享。
具体的共享方式有,管道、套接字、信号、共享内存等。
进程的概念
狭义的定义:进程是一段程序的执行过程
广义的定义:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基>本的执行单
- 动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
- 并发性:任何进程都可以同其他进程一起并发执行
- 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
- 异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推 进
- 结构特征:进程由程序、数据和进程控制块三部分组成;
多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果; 但是执行过程中,程序不能发生改变。
1. python中的多进程
python中的进程通过multiprocessing模块来实现
import os
import time
from random import randint
from multiprocessing import Process
def download_task(file):
print("start download, this process pid:{}".format(os.getpid()))
print("start download, this process parent pid:{}".format(os.getppid()))
print("start download file:{}".format(file))
time_to_download = randint(5, 10)
time.sleep(time_to_download)
print("{} download finished,cost time :{}".format(file, time_to_download))
def main():
start = time.time()
print("main current pid %d" % os.getpid())
print("main parent pid %d" % os.getppid())
args = ('tencent', 'ali')
process_list = []
# python中的多进程
for i in args:
p = Process(target=download_task, args=(i,))
p.start()
process_list.append(p)
for j in process_list:
j.join()
end = time.time()
print("total cost time %.2f" % (end - start))
if __name__ == '__main__':
main()
2.进程池
Pool即进程池,可以设置进程的数量。
import os
import time
from random import randint
from multiprocessing import Pool
def download_task(name):
print("current task parent pid:%d, child pid:%s" % (os.getppid(), os.getpid()))
time_to_download = randint(5, 10)
time.sleep(time_to_download)
print("download_task file %s total cost time:%d" % (name, time_to_download))
if __name__ == '__main__':
start = time.time()
total_download_time = 0
print("parent pid is:%d" % os.getpid())
p = Pool(processes=2)
for i in range(10):
p.apply_async(download_task, args=(i,))
print("wait for all process done")
p.close()
p.join()
end = time.time()
print("python pool total cost time %.2f, %d" % (end - start, total_download_time))
3.进程加锁
锁的作用是保证在同一时间内只运行一个进程
import time
import random
from multiprocessing import Process, Lock
def download_task(name):
lock.acquire()
download_time = random.randint(5, 10)
time.sleep(download_time)
print("download_task name:{}, download_time:{}".format(name, download_time))
lock.release()
lock = Lock()
if __name__ == '__main__':
start = time.time()
process_list = []
for i in range(10):
p = Process(target=download_task, args=(i,))
p.start()
process_list.append(p)
for j in process_list:
j.join()
end = time.time()
print("python_lock total cost time :{}".format(end - start))
4.进程之间的通信方式
这里介绍两种常见的通信方式,管道,队列
1.Pipe管道
import os
import time
from random import randint
from multiprocessing import Process, Pipe
def download_task(conn, name):
print("download_task current_pid:%d" % os.getpid())
download_time = randint(5, 10)
time.sleep(download_time)
conn.send(['download' + str(name)])
print("%s download_task finished download_time:%d" % (name, download_time))
if __name__ == '__main__':
start = time.time()
process_list = []
parent_conn, child_conn = Pipe()
for i in range(10):
p = Process(target=download_task, args=(child_conn, i))
p.start()
process_list.append(p)
for j in process_list:
j.join()
for k in range(10):
print(parent_conn.recv())
end = time.time()
print("this python_pipe total cost time: %.2f" % (end - start))
2.Queue队列
import os
import time
from multiprocessing import Process, Queue
def f(name, que):
print("start process current pid: %d" % os.getpid())
time.sleep(1)
que.put(['hello' + str(name)])
if __name__ == '__main__':
process_list = []
q = Queue()
for i in range(10):
p = Process(target=f, args=(i, q))
p.start()
process_list.append(p)
print(q.get())
for j in process_list:
j.join()
5.进程之间共享内存
通过Array,Value,Maneger等来实现进程之间的内存共享
1. Array,Value
"""进程之间共享内存"""
import os
import time
from multiprocessing import Process, Value, Array
def download_task(n, a, name):
time.sleep(1)
n.value = name * name
print("download_task name:{}".format(name))
for k in range(len(a)):
a[k] = -k # 添加到列表中
if __name__ == '__main__':
# 通过使用Value或者Array把数据存储在一个共享的内存表中
# 'd'和'i'参数是num和arr用来设置类型,d表示一个整数类型,i表示一个带符号的整型。
num = Value('i', 0)
arr = Array('d', range(10))
process_list = []
for i in range(10):
p = Process(target=download_task, args=(num, arr, i))
p.start()
process_list.append(p)
for j in process_list:
j.join()
print("download_task value:{}".format(num.value)) # 返回最后一个子进程运行的值
print("download_task arr:{}".format(arr[:]))
2. Manager
# 比共享内存灵活,但缓慢
# 支持list,dict,Namespace,Lock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value,Array
import os
import time
from multiprocessing import Process, Manager
def download_task(dm, name):
# print("download_task current pid:%d" % os.getpid())
dm[name] = name * name
# print("download_task dm:%s, name:%d" % (dm, name))
if __name__ == '__main__':
manager = Manager()
d = manager.dict()
process_list = []
for i in range(10):
p = Process(target=download_task, args=(d, i))
p.start()
process_list.append(p)
for j in process_list:
j.join()
print("download_task d:{}".format(d))