zoukankan      html  css  js  c++  java
  • Python【多线程与多进程】

    import time,threading

    print("=======串行方式、并行两种方式调用run()函数=======")
    def run():
    print('哈哈哈')

    #串行
    for i in range(5):
    run()

    #并行
    for i in range(5):
    t = threading.Thread(target=run) #实例化了一个线程
    t.start()


    print("======串行、并行方式统计网页下载时间=======")

    import requests
    #定义函数,用于发送http请求,获取网页的内容并写入文件
    data= {}
    def down_html(file_name,url):
    start_time = time.time()
    res = requests.get(url).content
    open(file_name+'.html','wb').write(res)
    end_time = time.time()
    run_time = end_time-start_time
    data[url] = run_time

    #定义一个字典,存放要请求的url地址
    urls = {
    'besttest':'http://www.besttest.cn',
    'niuniu':'http://www.nnzhp.cn',
    'dsx':'http://www.imdsx.cn',
    'cc':'http://www.cc-na.cn'
    }

    #串行方式下载网页
    start_time = time.time()
    for k,v in urls.items():
    down_html(k,v)
    end_time = time.time()
    run_time = end_time - start_time
    print('串行方式下载总共花时间:',run_time)


    #并行方式下载网页
    threads = []
    start_time = time.time()
    for k,v in urls.items(): #开启5个子线程,加上进程中有一个默认的主线程,一共是6个线程
    t = threading.Thread(target=down_html,args=(k,v)) #多线程的函数如果传参的话,必须得用args
    t.start()
    threads.append(t)

    for t in threads:
    #1、主线程等待5个子线程执行完毕,主线程接着运行主线程剩余余部分的代码,
    #2、不加上下面这行代码,则统计的子线程下载时间不对,下载时间取花费时间最长的那个子线程
    #3、如果子线程已经运行完毕,调用下方join()方法也不会报错
    t.join()

    end_time = time.time()
    run_time = end_time - start_time
    print('并行方式下载总共花时间:',run_time)
    print('并行方式各个网页下载花时间:',data)

    print("=========守护线程=========")
    def cry():
    time.sleep(3)
    print('哇哇哇.......')

    for i in range(3):
    t = threading.Thread(target=cry)
    #1、守护线程:只要主线程结束,那么子线程立即结束,不管子线程有没有运行完成。
    #2、setDaemon(True)方法把子线程设置成为守护线程
    #3、如何避免由于主线程代码运行完毕,而导致子线程被迫也结束运行的问题:在主线程代码部分time.sleep(3),sleep的时间大于3更好
    #4、去掉主线程部分的time.sleep(3)代码,如果主线程运行的比子线程快,则会导致子线程运行过程中突然中断
    t.setDaemon(True)
    t.start()

    print('Done,运行完成。')
    time.sleep(3)


    print("========线程锁==========")
    #线程为什么要加锁:多线程时,保证修改共享数据时有序的修改,不会产生数据修改混乱
    #在python2里面需要程序员手动加锁,python3里面不加锁也无所谓,默认会自动帮你加锁。

    num = 1
    lock = threading.Lock() #申请一把锁
    def update():
    time.sleep(1)
    global num
    lock.acquire() #加锁
    num+=1
    lock.release() #解锁
    ts = []
    for i in range(3):
    t = threading.Thread(target=update)
    t.start()
    ts.append(t)
    [t.join() for t in ts]
    print('多线程修改全局变量,修改后的值为:',num)

    print("==========多进程=========")
    import multiprocessing,threading
    def output():
    print('呵呵呵哈哈哈嘿嘿嘿')

    def execute(num):
    for i in range(num):
    t = threading.Thread(target=output)
    t.start()
    if __name__ == '__main__':
    for i in range(5):
    p = multiprocessing.Process(target=execute,args=(2,)) #启动5个进程,6个线程
    p.start()


    # 问题:为什么python的多线程不能利用多核CPU,但是咱们在写代码的时候,多线程的确是在并发,而且还比单线程快
    # 原因:因为GIL,python只有一个GIL,运行python时,就要拿到这个锁才能执行,在遇到I/O 操作时会释放这把锁。
    # 如果是纯计算的程序,没有 I/O 操作,解释器会每隔100次操作就释放这把锁,让别的线程有机会 执行(这个次数可以通sys.setcheckinterval
    # 来调整)同一时间只会有一个获得GIL线程在跑,其他线程都处于等待状态
    # 1、如果是CPU密集型代码(循环、计算等),由于计算工作量多和大,计算很快就会达到100,然后触发GIL的释放与在竞争,多个线程来回切换损耗资源,
    # 所以在多线程遇到CPU密集型代码时,单线程会比较快
    # 2、如果是IO密集型代码(文件处理、网络爬虫),开启多线程实际上是并发(不是并行),IO操作会进行IO等待,线程A等待时,自动切换到线程B,
    # 这样就提升了效率






  • 相关阅读:
    第二次冲刺个人工作总结06
    第二次冲刺个人工作总结05
    第十三周学习进度
    第二次冲刺工作总结04
    软件工程课堂作业——寻找水王2
    第二次冲刺个人工作总结03
    第二次冲刺周期个人工作总结02
    第二次冲刺个人工作总结01
    第二次冲刺会议
    git 的更新代码的取消
  • 原文地址:https://www.cnblogs.com/mtszw/p/9123157.html
Copyright © 2011-2022 走看看