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()
原文地址:https://www.cnblogs.com/zhen1996/p/9338599.html