爬虫核心基础第八讲(Queue,Lock/Rlock,Condition,Semaphore)

Queue

1.共享变量
2.queue队列 - 它本身是安全的 - 引用了 deque 双端队列

import time
import threading
from queue import Queue

def get_data_html(queue):
    # global data_list
    while True:
        url = queue.get()
        print('开始获取数据html的时间')
        time.sleep(2)
        print('获取数据html结束的时间')


def get_data_url(queue):
    # global data_list
    while True:
        print('开始获取数据url的时间')
        time.sleep(3)
        for item in range(30):
            # 添加
            queue.put('http://logic.org/{id}'.format(id=item))
        print('获取数据url结束的时间')


if __name__ == '__main__':
    # 设置队列
    data_url_queue = Queue(maxsize=1000)
    thread_url = threading.Thread(target=get_data_url,args=(data_url_queue,))
    for item in range(10):
        thread_html = threading.Thread(target=get_data_html,args=(data_url_queue,))
        thread_html.start()
    start_time = time.time()
    # 成对出现的
    data_url_queue.join()
    data_url_queue.task_done()
    # thread_url.start()
    print("中间运行时间:{}".format(time.time()-start_time))

Lock,Rlock

1.线程间的通讯问题
2.线程同步问题 - 为了解决结果不一致

'''

'''
import dis


def time(a):
    a += 1


def test(a):
    a -= 1
'''
0 LOAD_FAST                0 (a)
2 LOAD_CONST               1 (1)
4 INPLACE_ADD   +          1
6 STORE_FAST               0 (a)
'''

print(dis.dis(time))
print(dis.dis(test))


Module_thread_lock.py

'''
A(a,b)
acquire(a)
acquire(b)
                    资源竞争 - 互相等待
B(a,b)
acquire(b)
acquire(a)
'''

from threading import Lock
a = 0
lock = Lock()
def time():
    global a
    global lock
    for item in range(1000000):
        # 上锁
        lock.acquire()
        a += 1
        # 释放锁
        lock.release()


def test():
    global a
    global lock
    for item in range(1000000):
        # 上锁
        lock.acquire()
        a -= 1
        # 释放锁
        lock.release()


import threading

thread_1 = threading.Thread(target=time)
thread_2 = threading.Thread(target=test)

thread_1.start()
thread_2.start()

thread_1.join()
thread_1.join()
print(a)

1.用锁会影响性能
2.锁会引起死锁 资源竞争 - 互相等待

RLock - 可重入锁

'''

# '''
# import dis
#
#
# def time(a):
#     a += 1
#
#
# def test(a):
#     a -= 1
# '''
# 0 LOAD_FAST                0 (a)
# 2 LOAD_CONST               1 (1)
# 4 INPLACE_ADD   +          1
# 6 STORE_FAST               0 (a)
# '''
#
# print(dis.dis(time))
# print(dis.dis(test))
'''
A(a,b)
acquire(a)
acquire(b)
                    资源竞争 - 互相等待
B(a,b)
acquire(b)
acquire(a)
'''
from threading import Lock, RLock
a = 0
lock = RLock()
def time():
    global a
    global lock
    for item in range(1000000):
        # 上锁
        lock.acquire()
        # do_time(lock)
        lock.acquire()
        a += 1
        # 释放锁
        lock.release()
        lock.release()


def do_time(lock):
    # 上锁
    lock.acquire()
    # 0---------------------
    # 释放锁
    lock.release()


def test():
    global a
    global lock
    for item in range(1000000):
        # 上锁
        lock.acquire()
        a -= 1
        # 释放锁
        lock.release()


import threading

thread_1 = threading.Thread(target=time)
thread_2 = threading.Thread(target=test)

thread_1.start()
thread_2.start()

thread_1.join()
thread_1.join()
print(a)

Condition

通过condition完成双方协同聊天的功能
条件变量 主要用于复杂线程间的同步:
在调用with cond 之后才能调用 wait 和 notify方法
在condition 有2层锁, 一把底层锁会在线程调用wait方法的时候释放,上面的锁会在每次调用wait的时候分配一把并放入cond中的等待队列中;直到notify方法的唤醒。

import threading

from threading import Condition

'''
张三 : 你好,很高兴认识你     A
马六 : 我也是                B
张三 : 你是什么样的人      
马六 : 我是憨憨
张三 : 。。。
马六 : 。。。。。。
'''


class ZhangSan(threading.Thread):
    def __init__(self, lock):
        super().__init__(name='张三')
        self.lock = lock

    def run(self):
        lock.acquire()
        print("{} : 你好,很高兴认识你".format(self.name))
        lock.release()

        # lock.acquire()
        # print("{} : 你是什么样的人".format(self.name))
        # lock.release()


class MaLiu(threading.Thread):
    def __init__(self, lock):
        self.lock = lock
        super().__init__(name='马六')

    def run(self):
        lock.acquire()
        print("{} : 我也是".format(self.name))
        lock.release()

        # lock.acquire()
        # print("{} : 我是憨憨".format(self.name))
        # lock.release()

if __name__ == '__main__':
    lock = threading.Lock()
    zhang_san = ZhangSan(lock)
    ma_liu = MaLiu(lock)

    zhang_san.start()
    ma_liu.start()

Condition

import threading

from threading import Condition

'''
张三 : 你好,很高兴认识你     A
马六 : 我也是                B
张三 : 你是什么样的人      
马六 : 我是憨憨
张三 : 。。。
马六 : 。。。。。。
'''


class ZhangSan(threading.Thread):
    def __init__(self, cond):
        super().__init__(name='张三')
        self.cond = cond

    def run(self):
        with self.cond:
	        # self.cond.acquire()
	        print("{} : 你好,很高兴认识你".format(self.name))
	        self.cond.notify()
	        self.cond.wait()
	
	        print("{} : 你是什么样的人".format(self.name))
	        self.cond.notify()
	        self.cond.wait()
	        # self.cond.release()


class MaLiu(threading.Thread):
    def __init__(self, cond):
        self.cond = cond
        super().__init__(name='马六')

    def run(self):
        with self.cond:
	        # self.cond.acquire()
	        self.cond.wait()
	        print("{} : 我也是".format(self.name))
	        self.cond.notify()
	
	        self.cond.wait()
	        print("{} : 我是憨憨".format(self.name))
	        self.cond.notify()
	        # self.cond.release()

if __name__ == '__main__':
    cond = threading.Condition()
    zhang_san = ZhangSan(cond)
    ma_liu = MaLiu(cond)
    # 程序的执行顺序
    ma_liu.start()
    zhang_san.start()

Semaphore

'''
读和写
Semaphroe():用于控制进入的数量的锁, 信号量
'''
import threading
# threading.Semaphore()
import time


class GetUrl(threading.Thread):
    def __init__(self, sem):
        super().__init__()
        self.sem = sem

    def run(self):
        # list.append()
        for item in range(20):
            # 上锁
            self.sem.acquire()
            html_thread = HtmlSpider('http://news.baidu.com/{}'.format(item), self.sem)
            html_thread.start()


class HtmlSpider(threading.Thread):
    def __init__(self, url, sem):
        super().__init__()
        self.url = url
        self.sem = sem

    def run(self):
        time.sleep(2)
        print("获取了一页html详情信息!")
        # 释放锁
        self.sem.release()


if __name__ == '__main__':
    # 只允许并发3个
    sem = threading.Semaphore(3)
    url_threads = GetUrl(sem)
    url_threads.start()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值