Pathon Day08

正则表达式

  • ()代表提取目标项

import requests
import re

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
url = 'http://www.89ip.cn/index_1.html'
response = requests.get(url,headers=headers)
response.encoding = 'utf8'
html = response.text 
#print(html)    
title = re.findall('\n.*\t(.*?)\t\t',html)
print(title)
""" 
运行结果:
['118.24.182.249', '8081', '    广西柳州市高新区', '视虎科技有限公司', '2019/08/23 17:45:04', '221.7.211.246', '51864', '    广西桂林市', '联通', '2019/08/23 17:45:04', '182.34.34.85', '9999', '    山东省烟台市', '电信', '2019/08/23 17:45:04', '122.136.212.132', '53281', '    吉林省延边州', '联通', '2019/08/23 17:45:04', '163.204.246.118', '9999', '    广东省汕尾市陆丰县', '联通', '2019/08/23 17:45:04', '222.89.32.178', '9999', '    河南省济源市', '电信', '2019/08/23 17:45:04', '183.146.29.60', '8888', '    浙江省金华市', '电信', '2019/08/23 17:45:04', '1.198.73.24', '9999', '    河南省郑州市', '电信', '2019/08/23 17:45:04', '183.146.213.198', '80', '
浙江省金华市', '电信', '2019/08/23 17:45:04', '27.37.46.230', '9000', '    广东省东莞市', '联通', '2019/08/23 17:45:04', '222.241.190.141', '80', '    湖南省衡阳市',
'电信', '2019/08/23 17:45:04', '36.255.86.239', '82', '    浙江省', '电信', '2019/08/23 17:45:04', '117.28.98.55', '8118', '    福建省泉州市', '电信', '2019/08/23 17:45:04', '118.26.170.209', '8080', '    北京市', '北京铜牛信息科技股份有限公司BGP节点', '2019/08/23 17:45:04', '120.234.63.196', '3128', '    广东省佛山市', '移动', '2019/08/23 17:45:04']
 """

线程通信强化

import threading
import time

def goevent():
    e = threading.Event()  # 事件

    def go():
        for i in range(10):
            e.wait()  # 等待事件,线程卡顿,等待set消息,只调用一次
            e.clear() # 重置线程等待
            print("go",i)

    threading.Thread(target=go).start() # 创建一个线程
    return e


t = goevent()
for i in range(5):
    time.sleep(i)
    t.set()
    """ 
    运行结果:
    go 0
    go 1
    go 2
    go 3
    go 4
     """

condition线程通讯与事件

  • wait 此方法释放底层的锁,然后阻塞,直到它通过notify()或notify_all()调用唤醒相同的条件在另一个线程中变量,或直到发生可选的超时。一旦唤醒或超时,它重新获得锁定并返回。
    -notify 在这种情况下唤醒一个或多个线程,如果有的,调用线程没有获得这个方法的锁称为,引发了一个RuntimeError。这个方法至多唤醒n个等待条件的线程变量; 如果没有线程正在等待,那么这是一个无操作。

代码逻辑 cond只有一个,线程1线锁定cond,当线程1跑到i==5的时候,此时进入condition等待,将资源释放出来,这时候线程2进入,一口气全部跑完,跑到最后以cond.notifly通知,将资源再放出来,此时线程1重新锁定

import threading
import time

def go1():
    with cond:
        for i in range(10):
            time.sleep(1)
            print(threading.current_thread().name, i)
            if i == 5:
                cond.wait()  # 等待,只有在其他相同线程条件变量唤醒时才继续执行
                print("hahahha")
   #wait()
  def go2():
    with cond:  # 使用条件变量
        for i in range(10):
            time.sleep(1)
            print(threading.current_thread().name, i)
        cond.notify()  # 通知唤醒其他线程
#notify()
cond = threading.Condition()  # 线程条件变量
threading.Thread(target=go1).start()
threading.Thread(target=go2).start()
""" 
运行结果:
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Thread-1 5
Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
Thread-2 5
Thread-2 6
Thread-2 7
Thread-2 8
Thread-2 9
hahahha
Thread-1 6
Thread-1 7
Thread-1 8
Thread-1 9
 """

线程调度

  • 逻辑:
    首先明确wait()调用后下面的程序是不会运行的,
    首先线程1线绑定cond,打印出0后,线程1进入等待(注意此时线程2并没有绑定),线程2绑定cond,打印出1后
    notify给线程1唤醒wait(),(此时才打印出"haha"),同时线程2的wait激活进入等待,同时1打印出2,并唤醒线程2如此循环
import threading
import time


def go1():
    with cond:
        for i in range(0, 10, 2):
            time.sleep(1)
            print(threading.current_thread().name, i)
            cond.wait()
            # print("hahah")
            cond.notify()


def go2():
    with cond:
        for i in range(1, 10, 2):
            time.sleep(1)
            print(threading.current_thread().name, i)
            cond.notify()
            cond.wait()


cond = threading.Condition()  # 线程条件变量
threading.Thread(target=go1).start()
threading.Thread(target=go2).start()
""" 
运行结果:
Thread-1 0
Thread-2 1
Thread-1 2
Thread-2 3
Thread-1 4
Thread-2 5
Thread-1 6
Thread-2 7
Thread-1 8
Thread-2 9
 """

生产者消费者模式

# # 在队列中,有多个生产者将商品放入队列,同时又多个消费者在队列的另一头获取商品,一般
# # 情况下会产生线程冲突,但是python已经将此处理好了,也就是说在将商品放入队列的过程中无需考虑线程冲突
# import threading
# import queue
# import time
# import random
#
#
# # 生产
# class CreatorThread(threading.Thread):
#     def __init__(self, index, myqueue):
#         threading.Thread.__init__(self)
#         self.index = index  # 索引
#         self.myqueue = myqueue  # 队列
#
#     def run(self):
#         while True:
#             time.sleep(3)
#             num = random.randint(1, 1000000)
#             self.myqueue.put("in put 生产者" + str(self.index) + str(num))
#             print("in put 生产者", str(self.index), str(num))
#         # self.myqueue.task_done() # 完成任务
#
#
# # 消费
# class BuyerThread(threading.Thread):
#     def __init__(self, index, myqueue):
#         threading.Thread.__init__(self)
#         self.index = index  # 索引
#         self.myqueue = myqueue  # 队列
#
#     def run(self):
#         while True:
#             time.sleep(1)
#             item = self.myqueue.get()  # 获取数据,拿不到一直等待
#             if item is not None:
#                 print("消费者:" , item,'\n')
#
#
# myqueue = queue.Queue(10)  # 0代表无限,内存有多大装多大,
# for i in range(3):  # 3个生产者同时放入
#     CreatorThread(i, myqueue).start()  # 创建生产者
#
# for j in range(8):# 8个消费者同时获取,最多只能获取到生产者生产的
#     BuyerThread(j, myqueue).start()  # 创建消费者
import threading
import time
import queue

q = queue.Queue(maxsize=10)


def producer(name):  # 生产者
    count = 1
    while True:
        q.put("骨头%s" % count)
        print("生产了骨头", count)
        count += 1
        time.sleep(0.5)


def consumer(name):  # 消费者
    while True:
        print("[%s]取到[%s]并且吃了它..." % (name, q.get()))
        time.sleep(1)


p = threading.Thread(target=producer, args=("Tim",))
c1 = threading.Thread(target=consumer, args=("King",))
c2 = threading.Thread(target=consumer, args=("Wang2",))
c3 = threading.Thread(target=consumer, args=("Wang3",))
c4 = threading.Thread(target=consumer, args=("Wang4",))
c5 = threading.Thread(target=consumer, args=("Wang5",))

p.start()
c1.start()
c2.start()
c3.start()
c4.start()
c5.start()
""" 
运行结果:
生产了骨头 1
[King]取到[骨头1]并且吃了它...
生产了骨头 2
[Wang2]取到[骨头2]并且吃了它...
生产了骨头 3
[Wang3]取到[骨头3]并且吃了它...
生产了骨头 4
[Wang4]取到[骨头4]并且吃了它...
生产了骨头 5
[Wang5]取到[骨头5]并且吃了它...
生产了骨头 6
[King]取到[骨头6]并且吃了它...
生产了骨头 7
[Wang2]取到[骨头7]并且吃了它...
生产了骨头 8
[Wang3]取到[骨头8]并且吃了它...
生产了骨头 9
[Wang4]取到[骨头9]并且吃了它...
生产了骨头 10
[Wang5]取到[骨头10]并且吃了它...
……
 """

线程池

import threadpool  # 需要安装

import time


def show(name):
    print('hello', name)


namelist = ["A", "B", "C", "D"]
start = time.time()
pool = threadpool.ThreadPool(7)  # 线程池最大数,貌似还要远大于列表长度
requests = threadpool.makeRequests(show, namelist)  # 设置参数,函数,参数列表
print(requests)
print()
for req in requests:
    pool.putRequest(req)  # 压入线程池开始执行

end = time.time()
print(end - start)

定时线程

import time
import threading
import os

'''
def show():
    os.system("say hello")


mythreading = threading.Timer(3, show).start()  # 延时3秒启动show函数,只启动一次
num = 0
while True:
    print('第', num, "秒")
    time.sleep(1)
    num += 1
    
    
'''


def show():
    while True:
        time.sleep(3)
        print("say hello")


mythreading = threading.Timer(3, show).start()  # 延时3秒启动show函数,只启动一次,不阻塞主线程
num = 0
while True:
    print('第', num, "秒")
    time.sleep(1)
    num += 1

#  mythreading.cancel() # 因为cancel取消了线程的执行,所以fun()函数不会被执行

""" 
运行结果:
第 0 秒
第 1 秒
第 2 秒
第 3 秒
第 4 秒
第 5 秒
say hello
第 6 秒
第 7 秒
第 8 秒
say hello
第 9 秒
第 10 秒
第 11 秒
say hello
第 12 秒
第 13 秒
第 14 秒
say hello
第 15 秒
第 16 秒
第 17 秒
say hello
第 18 秒
第 19 秒
第 20 秒
say hello
第 21 秒
第 22 秒
第 23 秒
say hello
第 24 秒
第 25 秒
第 26 秒
say hello
 """

with的作用

import threading

num = 0  # 全局变量可以在线程之间传递
mutex = threading.Lock()  # 创建一个锁,threading.Lock()是一个类


class Myhtread(threading.Thread):
    def run(self):
        global num
        with mutex:
            for i in range(1000000):  # 数字小的时候还是不会产生线程冲突的
                num += 1

        print(num)


mythread = []
for i in range(5):
    t = Myhtread()
    t.start()
    mythread.append(t)

for thread in mythread:
    thread.join()  # 或者直接将thread.join()加入for i in range(5),也能解决线程冲突,但是貌似就变成单线程了

print("game over")
'''
with 作用自动打开和释放,python3新功能
运行结果:
1000000
2000000
3000000
4000000
5000000
game over

'''

TLS

# 线程独立
import threading
import time

data = threading.local()  # 每个线程私有独立储存空间

t1 = lambda x: x + 1
t2 = lambda x: x + "1"


def printdata(func, x):
    data.x = x  # data = threading.local() 本质上是一个类,此处为动态绑定
    print(id(data.x))  # 不同地址互相独立data.x 在每个线程中是独立的
    for i in range(5):
        data.x = func(data.x)
        print(threading.current_thread().name, data.x)


threading.Thread(target=printdata, args=(t1, 1)).start()
threading.Thread(target=printdata, args=(t2, "1")).start()
""" 
运行结果:
1387120784
Thread-1 2
Thread-1 3
Thread-1 4
Thread-1 5
Thread-1 6
18342240
Thread-2 11
Thread-2 111
Thread-2 1111
Thread-2 11111
Thread-2 111111
 """

后台线程

import threading
import time
# import win32api  # 引用系统函数


class Mythread(threading.Thread):  # 继承threading.Thread
    def run(self):  # run重写,
        # win32api.MessageBox(0, "你的账户很危险", "来自支付宝的问候", 6)
        print('hahah')


mythread = []  # 集合list
for i in range(5):
    t = Mythread()  # 初始化
    t.setDaemon(True) #后台线程,主线程不等后台线程
    t.start()
    mythread.append(t)  # 加入线程集合

# threading.Thread默认是前台进程,主线程必须等前台。
print("game over")
""" 
运行结果:
hahah
hahah
hahah
hahah
hahah
game over
"""

你可能感兴趣的:(Pathon Day08)