7.19python昨日复习和多线程(2)
2018-7-19 21:39:49 我觉得这次的笔记是非常非常完美的!!!明天继续 睡觉去啦!
傍黑时候和晴宝打电话,她特能说,很喜欢这种感觉,有好多东西要和你分享!
1.复习!
# !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/19 10:12 # !@Author TrueNewBee # 今天和明天 多线程 # 协程 + IO模型 # 进程池所有内容: # 管道 # 数据的共享 Manager dic list # 进程池 # cpu个数+1 # ret = map(func, iterable) # 异步 自带close和join # 所有结果的[] # apply() # 同步的 : 只有当func执行完之后,才会继续向下执行其他的代码 # apply(func, args=()) # 返回值就是func的return # apply_async # 异步的:当func被注册进入一个进程之后,程序就继续向下执行 # apply_async(func, args()) # 返回值: apply_async返回的对象 # 为了用户能从中获取func的返回对象 obj.get() # get会阻塞直到对应的func执行完毕拿到结果 # 使用apply_async给进程池分配任务,需要线close()后join来保持多进程和主进程代码的同步性
2.回调函数
# !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/19 10:22 # !@Author TrueNewBee # 回调函数 from multiprocessing import Pool def func1(n): return n+1 def func2(m): print(m) if __name__ == '__main__': p = Pool(5) for i in range(10, 20): p.apply_async(func1, args=(i, ), callback=func2) p.close() p.join()
3.爬取数据例子
# !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/19 10:40 # !@Author TrueNewBee import requests from multiprocessing import Pool # 200 网页正常 # 404 网页找不到了 # 502 504 # 回调函数在主进程进行,因为是异步,不让主进程闲着,多做点东西! def get(url1): response = requests.get(url1) if response.status_code == 200: return url1, response.content.decode('utf-8') def call_back(args): url2, content = args print(url2, len(content)) url_list = [ 'https://www.cnblogs.com/', 'http://www.baidu.com/', 'http://www.jd.com/' ] if __name__ == '__main__': p = Pool(5) for url in url_list: p.apply_async(get, args=(url,), callback=call_back) p.close() p.join()
4.爬虫
# !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/19 11:23 # !@Author TrueNewBee # 爬取猫眼榜单数据,使用了线程池回调函数 import re from urllib.request import urlopen from multiprocessing import Pool def get_page(url,pattern): response = urlopen(url).read().decode('utf-8') return pattern, response # 正则表达式编译结果 网页内容 def parse_page(info): pattern, page_content = info res = re.findall(pattern, page_content) for item in res: dic = { 'index': item[0].strip(), 'title': item[1].strip(), 'actor': item[2].strip(), 'time': item[3].strip(), } print(dic) if __name__ == '__main__': # 正则要写的好 regex = r'<dd>.*?<.*?class="board-index.*?>(\d+)</i>.*?title="(.*?)".*?class="movie-item-info".*?<p class="star">(.*?)</p>.*?<p class="releasetime">(.*?)</p>' pattern1 = re.compile(regex, re.S) url_dic = { 'http://maoyan.com/board/7':pattern1, } p = Pool() res_l = [] for url, pattern in url_dic.items(): res = p.apply_async(get_page, args=(url, pattern), callback=parse_page) res_l.append(res) for i in res_l: i.get()
5.线程
# !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/19 15:50 # !@Author TrueNewBee # import os # import time # from threading import Thread # """多线程并发,都在同一个进程运行""" # # # def func(n): # time.sleep(1) # 全部线程并发睡1s 然后打印 # print(n, os.getpid()) # # # print('主线程:', os.getpid()) # for i in range(10): # t = Thread(target=func, args=(i, )) # t.start() """使用面向对象方式开启线程""" # class MyTread(Thread): # def __init__(self, arg): # super().__init__() # self.arg = arg # # def run(self): # time.sleep(1) # print(self.arg) # # # t = MyTread(10) # t.start() # threading模块: # multiprocessing模块的完全模仿threading模块的接口, # 二者在使用层面上有很大的相似地方 """修改全局变量""" # 在同一个进程多个线程之间的数据是共享的 # def func1(a): # global g # g = 0 # print(g, a, os.getpid()) # # # g = 100 # t_list = [] # for i in range(10): # t = Thread(target=func1, args=(i, )) # t.start() # t_list.append(t) # for t in t_list: # t.join() # print(g) # 进程 是最小的内存分配单位 # 线程 是操作系统调度的最小单位 # 线程被cpu执行了 # 进程内至少含有一个线程 # 进程中可以开启多个线程 # 开启一个线程所需要的时间要远远小于开启一个进程 # 多个线程内部有自己的数据栈,数据不共享 # 全局变量在多个线程之间是共享的 # 在CPython解释器下的python程序 在同一时刻 多线程只能有一个线程cpu被执行 # 高CPU(用多进程处理): 计算类 -----高CPU利用率 不占优势 # 高IO(用多线程处理): 爬取网页 200个网页 # qq聊天 send recv # 处理日志文件 读文件 # 处理web请求 # 读取数据库 写数据库 import time from threading import Thread from multiprocessing import Process """多线程与多进程时间对比""" def func(n): n+1 if __name__ == '__main__': start = time.time() t_list = [] for i in range(100): t = Thread(target=func, args=(i, )) t.start() t_list.append(t) for t in t_list: t.join() t1 = time.time() - start start1 = time.time() p_list = [] for i in range(100): p = Process(target=func, args=(i, )) p.start() p_list.append(t) for p in p_list: p.join() t2 = time.time() - start1 print(t1, t2)
6.线程模块中其他方法
# !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/19 21:26 # !@Author TrueNewBee import threading import time def func(n): time.sleep(0.5) # 查看线程名字和id print(n, threading.current_thread(), threading.get_ident()) for i in range(10): threading.Thread(target=func, args=(i, )).start() print(threading.current_thread()) print(threading.active_count()) # 查看所有线程数 11 加上主线程 print(threading.enumerate())
7. 多线程写 socket sever
sever端
# !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/19 21:06 # !@Author TrueNewBee import socket from threading import Thread def chat(conn1): conn1.send(b'hello') msg = conn1.recv(1024).decode('utf-8') print(msg) inp = input(">>").encode('utf-8') conn1.send(inp) conn1.close() if __name__ == '__main__': sk = socket.socket() sk.bind(('127.0.0.1', 8080)) sk.listen() while True: conn, add = sk.accept() # 创建一个多线程实现多线程通讯 Thread(target=chat, args=(conn, )).start() sk.close()
client端 (多线程中可以用input 而多进程中不可以用input)
# !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/19 21:07 # !@Author TrueNewBee import socket sk = socket.socket() sk.connect(('127.0.0.1', 8080)) msg = sk.recv(1024) print(msg) inp = input('>>>>').encode('utf-8') # 多线程可以用input,多进程不可以用 sk.send(inp) sk.close()