#对于io操作来说,多线程和多进程性能差别不大
#1.通过Thread类实例化 import time
import threading def get_detail_html(url):
print("get detail html started")
time.sleep(2)
print("get detail html end") def get_detail_url(url):
print("get detail url started")
time.sleep(4)
print("get detail url end") #2. 通过集成Thread来实现多线程 class GetDetailHtml(threading.Thread):
def __init__(self, name):
super().__init__(name=name) def run(self):
print("get detail html started")
time.sleep(2)
print("get detail html end") class GetDetailUrl(threading.Thread):
def __init__(self, name):
super().__init__(name=name) def run(self):
print("get detail url started")
time.sleep(4)
print("get detail url end") if __name__ == "__main__":
thread1 = GetDetailHtml("get_detail_html")
thread2 = GetDetailUrl("get_detail_url")
start_time = time.time()
thread1.start()
thread2.start() thread1.join()
thread2.join() #当主线程退出的时候, 子线程kill掉
print ("last time: {}".format(time.time()-start_time))

线程间通信 -Queue

#通过queue的方式进行线程间同步
from queue import Queue import time
import threading def get_detail_html(queue):
#爬取文章详情页
while True:
url = queue.get()
# for url in detail_url_list:
print("get detail html started")
time.sleep(2)
print("get detail html end") def get_detail_url(queue):
# 爬取文章列表页
while True:
print("get detail url started")
time.sleep(4)
for i in range(20):
queue.put("http://projectsedu.com/{id}".format(id=i))
print("get detail url end") #1. 线程通信方式- 共享变量 if __name__ == "__main__":
detail_url_queue = Queue(maxsize=1000) thread_detail_url = threading.Thread(target=get_detail_url, args=(detail_url_queue,))
for i in range(10):
html_thread = threading.Thread(target=get_detail_html, args=(detail_url_queue,))
html_thread.start()
# # thread2 = GetDetailUrl("get_detail_url")
start_time = time.time()
# thread_detail_url.start()
# thread_detail_url1.start()
#
# thread1.join()
# thread2.join()
detail_url_queue.task_done()
detail_url_queue.join() #当主线程退出的时候, 子线程kill掉
print ("last time: {}".format(time.time()-start_time))

线程锁,lock和Rlock

from threading import Lock, RLock, Condition #可重入的锁

#在同一个线程里面,可以连续调用多次acquire, 一定要注意acquire的次数要和release的次数相等
total = 0
lock = RLock()
def add():
#1. dosomething1
#2. io操作
# 1. dosomething3
global lock
global total
for i in range(1000000):
lock.acquire()
lock.acquire()
total += 1
lock.release()
lock.release() def desc():
global total
global lock
for i in range(1000000):
lock.acquire()
total -= 1
lock.release() import threading
thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start() #
thread1.join()
thread2.join()
print(total) #1. 用锁会影响性能
#2. 锁会引起死锁
#死锁的情况 A(a,b)
"""
A(a、b)
acquire (a)
acquire (b) B(a、b)
acquire (a)
acquire (b)
"""

条件变量-线程间同步

import threading

#条件变量, 用于复杂的线程间同步
# class XiaoAi(threading.Thread):
# def __init__(self, lock):
# super().__init__(name="小爱")
# self.lock = lock
#
# def run(self):
# self.lock.acquire()
# print("{} : 在 ".format(self.name))
# self.lock.release()
#
# self.lock.acquire()
# print("{} : 好啊 ".format(self.name))
# self.lock.release()
#
# class TianMao(threading.Thread):
# def __init__(self, lock):
# super().__init__(name="天猫精灵")
# self.lock = lock
#
# def run(self):
#
# self.lock.acquire()
# print("{} : 小爱同学 ".format(self.name))
# self.lock.release()
#
# self.lock.acquire()
# print("{} : 我们来对古诗吧 ".format(self.name))
# self.lock.release() #通过condition完成协同读诗 class XiaoAi(threading.Thread):
def __init__(self, cond):
super().__init__(name="小爱")
self.cond = cond def run(self):
with self.cond:
self.cond.wait()
print("{} : 在 ".format(self.name))
self.cond.notify() self.cond.wait()
print("{} : 好啊 ".format(self.name))
self.cond.notify() self.cond.wait()
print("{} : 君住长江尾 ".format(self.name))
self.cond.notify() self.cond.wait()
print("{} : 共饮长江水 ".format(self.name))
self.cond.notify() self.cond.wait()
print("{} : 此恨何时已 ".format(self.name))
self.cond.notify() self.cond.wait()
print("{} : 定不负相思意 ".format(self.name))
self.cond.notify() class TianMao(threading.Thread):
def __init__(self, cond):
super().__init__(name="天猫精灵")
self.cond = cond def run(self):
with self.cond:
print("{} : 小爱同学 ".format(self.name))
self.cond.notify()
self.cond.wait() print("{} : 我们来对古诗吧 ".format(self.name))
self.cond.notify()
self.cond.wait() print("{} : 我住长江头 ".format(self.name))
self.cond.notify()
self.cond.wait() print("{} : 日日思君不见君 ".format(self.name))
self.cond.notify()
self.cond.wait() print("{} : 此水几时休 ".format(self.name))
self.cond.notify()
self.cond.wait() print("{} : 只愿君心似我心 ".format(self.name))
self.cond.notify()
self.cond.wait() if __name__ == "__main__":
from concurrent import futures
cond = threading.Condition()
xiaoai = XiaoAi(cond)
tianmao = TianMao(cond) #启动顺序很重要
#在调用with cond之后才能调用wait或者notify方法
#condition有两层锁, 一把底层锁会在线程调用了wait方法的时候释放, 上面的锁会在每次调用wait的时候分配一把并放入到cond的等待队列中,等到notify方法的唤醒
xiaoai.start()
tianmao.start()

Semaphore 是用于控制进入数量的锁

#Semaphore 是用于控制进入数量的锁
#文件, 读、写, 写一般只是用于一个线程写,读可以允许有多个 #做爬虫
import threading
import time class HtmlSpider(threading.Thread):
def __init__(self, url, sem):
super().__init__()
self.url = url
self.sem = sem def run(self):
time.sleep(2)
print("got html text success")
self.sem.release() class UrlProducer(threading.Thread):
def __init__(self, sem):
super().__init__()
self.sem = sem def run(self):
for i in range(20):
self.sem.acquire()
html_thread = HtmlSpider("https://baidu.com/{}".format(i), self.sem)
html_thread.start() if __name__ == "__main__":
sem = threading.Semaphore(3)
url_producer = UrlProducer(sem)
url_producer.start()

多线程复习 Rlock ,Condition,Semaphore的更多相关文章

  1. 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent

    [源码下载] 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEve ...

  2. Java多线程系列——信号量:Semaphore

    简介 信号量为多线程协作提供了更为强大的控制方法.也可以说,信号量是对锁的扩展.无论是内部锁 synchronized 还是重入锁 ReentrantLock,一次都只允许一个线程访问一个资源,而信号 ...

  3. python2.7 threading RLock/Condition文档翻译 (RLock/Condition详解)

    RLock Objects 可重入锁是一个同步原语,它可以被同一个线程多次获取.在内部,除了原始锁使用的锁定/解锁状态之外,它还使用“线程拥有”和“递归级别”的概念.在锁定状态下,某些线程拥有锁:在未 ...

  4. Java多线程-新特征-信号量Semaphore

    简介信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确.合理的使用公共资源. 概念Semaphore分为单值和多值两种,前者只能 ...

  5. java多线程,多线程加锁以及Condition类的使用

    看了网上非常多的运行代码,很多都是重复的再说一件事,可能对于java老鸟来说,理解java的多线程是非常容易的事情,但是对于我这样的菜鸟来说,这个实在有点难,可能是我太菜了,网上重复的陈述对于我理解这 ...

  6. 多线程模块的condition对象

    Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方 ...

  7. 多线程条件通行工具——Semaphore

    Semaphore的作用是,限制线程通行的数量,如果线程进入时达到通行数量,便等待其它正在通行的线程释放. acquire()获取通行 release()释放通行 availablePermits() ...

  8. C# 多线程之一:信号量Semaphore

    通过使用一个计数器对共享资源进行访问控制,Semaphore构造器需要提供初始化的计数器(信号量)大小以及最大的计数器大小 访问共享资源时,程序首先申请一个向Semaphore申请一个许可证,Sema ...

  9. 多线程09-Lock和Condition

    1.概念 Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. 2. ...

随机推荐

  1. NProgress.js加载进度插件的简单实用方法

    NProgress.js 说明: NProgress是基于jquery的,且版本要 >1.8 下载地址: https://github.com/rstacruz/nprogress API: N ...

  2. Java学习个人备忘录之内部类

    内部类: 将一个类定义在另一个类的里面,对里面那个类就称为内部类. class Outer { private int num = 3; class Inner //它想访问Outer中的num, 如 ...

  3. from module import 和 import 的区别

    最近在用codecademy学python,遇到一些题目错误,小小记录一下 如from math import sqrt是把sqrt作为本文件的方法导入进来了,使用的时候只需要直接调用sqrt. 而如 ...

  4. 软工1816 · Alpha冲刺(2/10)

    团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 与前后端敲定接口设计的细节 重新理清业务逻辑,对项目最初的设想进行一定修正 跟 ...

  5. Alpha 冲刺(3/10)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 协助后端界面的开发 搭建项目运行的服务器环境 ...

  6. iOS- 封装单例宏

    在项目中,我们需要全局只有一个实例,节省不必要的内存,这时我们就需要使用里单例生成对象. 这时把单例的代码封装成宏,就能方便我们下次使用了. 在.h .m里直接导入头文件,调用 传入类名即可! sin ...

  7. <Android>对话框的使用

    Android系统提供四种对话框:警告对话框(AlertDialog),进度对话框(ProgressDialog),日期选择对话框(DatePickerDialog)和时间选择对话框(TimePick ...

  8. 3dContactPointAnnotationTool开发日志(九)

      今天的任务是实现选中接触点功能并添加模型或接触点的属性改变功能,先从最简单的位置x,y,z改变入手,于是创建了一个面板(PanelStatus),添加了几个InputField来让用户输入数值改变 ...

  9. ZOJ 1711 H-Sum It Up

    https://vjudge.net/contest/67836#problem/H Given a specified total t and a list of n integers, find ...

  10. python 查看趴下来的数据

    #coding=utf-8 import re from lxml import etree import requests def requests_view(response): import w ...