# coding=utf-8
# 多进程
# # multiprocessing
# > 要充分的利用多核CPU资源。需要使用多进程,这个包叫multiprocessing
# 借助它,可以轻松完成从单进程到并发执行的转换。
# 提供了Process、Queue、Pipe、Lock 等组件。
# # # Process
# > 基本使用
# 在 multiprocessing 中,每一个进程都用一个 Process 类来表示。首先看下它的 API
# Process([group [, target [, name [, args [, kwargs]]]]])
# target表示调用对象,你可以传入方法的名字
# args 表示被调用对象的位置参数元组,比如 target 是函数 a,他有两个参数 m,n,那么 args 就传入 (m, n) 即可
# Kwargs 表示调用对象的字典
# name 是别名,相当于给这个进程取一个名字
# group分组,实际上不适用
#
# import multiprocessing
# import time
#
# def process(num):
# time.sleep(num)
# print("Process",num)
#
# if __name__ == '__main__':
# for i in range(5):
# p = multiprocessing.Process(target=process,args=(i,))
# p.start()
#
# print("CPU number:" + str(multiprocessing.cpu_count()))
# # CPU number:8
# for p in multiprocessing.active_children():
# print(f"Child process name:{p.name} id {str(p.pid)}")
# """
# Child process name:Process-3 id 17376
# Child process name:Process-1 id 17932
# Child process name:Process-4 id 14996
# Child process name:Process-5 id 892
# Child process name:Process-2 id 19784
# """
# print('Process Ended')
# 可以通过cpu_count()方法还有active_children()方法获取当前机器的CPU核心数量以及得到目前所有的运行的进程。
# 自定义类
# from multiprocessing import Process
# import time
#
#
# class MyProcess(Process):
# def __init__(self,loop):
# Process.__init__(self)
# self.loop = loop
#
# def run(self):
# for count in range(self.loop):
# time.sleep(1)
# print('Pid: '+str(self.pid)+" LoopCount: "+str(count))
#
# if __name__ == '__main__':
# for i in range(2,5):
# p = MyProcess(i)
# p.start()
# # daemon
# > 这里介绍一个属性,叫做daemon。每个线程都可以单独设置它的属性,如果设置为True,
# 当父类进程的结束后,子进程会自动被终止。
# daemon=True
# 在后面要加join()方法
# 这样主节点就会等所有的子节点运行完毕在结束
# from multiprocessing import Process
# import time
#
#
# class MyProcess(Process):
# def __init__(self,loop):
# Process.__init__(self)
# self.loop = loop
#
# def run(self):
# for count in range(self.loop):
# time.sleep(1)
# print('Pid: '+str(self.pid)+" LoopCount: "+str(count)+ "\n")
#
# if __name__ == '__main__':
# for i in range(2,5):
# p = MyProcess(i)
# p.daemon = True
# p.start()
# p.join()
#
# print("Main process Ended!")
# # Lock
# > 使用Lock就可以避免进程同时占用资源而导致的一些问题
# from multiprocessing import Process,Lock
# import time
#
# class MyProcess(Process):
# def __init__(self,loop,lock):
# Process.__init__(self)
# self.loop = loop
# self.lock = lock
#
# def run(self):
# for count in range(self.loop):
# time.sleep(0.1)
# self.lock.acquire() # 获取锁
# print("Pid "+str(self.pid)+" LoopCount "+str(count))
# self.lock.release() # 释放锁
#
# if __name__ == '__main__':
# lock = Lock()
# for i in range(10,15):
# p = MyProcess(i,lock)
# p.start()
# # Pool
# > Pool可以提供指定数量的进程,给用户调用,
# 当有新的请求提交到Pool中,如果进程池没有满,就会创建有一个新的进程俩执行请求
# 如果已经满了,该请求会等待,直到进程池中的进程结束,才会创建新的进程
# Pool 的用法有阻塞和非阻塞两种方式
# # 非阻塞(apply_async) 阻塞(apply)
# from multiprocessing import Lock,Pool
# import time
#
# def function(index):
# print("Start process",index)
# time.sleep(3)
# print("End process",index)
# # return index
#
# if __name__ == '__main__':
# pool = Pool(processes=3)
# for i in range(4):
# pool.apply_async(function,(i,)) # 非阻塞
# pool.apply(function,(i,)) # 阻塞
#
# print("started processes")
# # pool.terminate() # terminate () 结束工作进程,不在处理未完成的任务。
# pool.close() # 关闭pool,使其不在接收新任务
# pool.join() # join () 主进程阻塞,等待子进程的退出, join 方法要在close 或terminate 之后使用
# print('Subprocess done')
# # # map方法
# > 另一个非常好用的map方法,如果有一堆数据要处理,每一项都需要经过一个方法来处理,可以使用map方法
#
import multiprocessing
import requests
def scrape(url):
try:
print(requests.get(url))
except requests.exceptions.ConnectionError: # 找出网络请求失败的url
print("Error Occured",url)
finally:
print("url",url,"scraped")
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=3) # 初始化一个Pool,指定进程数3
# pool = multiprocessing.Pool() # 如果不指定会自动分配url
urls = [
'https://www.baidu.com',
'http://www.meituan.com/',
'http://blog.csdn.net/',
'http://xxxyxxx.net'
]
pool.map(scrape,urls)
# map函数可以遍历每个url,然后对其他分别执行scrape方法