zoukankan      html  css  js  c++  java
  • python学习笔记(二十七)多线程与多进程

    线程是程序里面的最小执行单元。

    进程是资源的集合。

    线程是包含在一个进程里面,一个进程可以有多个线程,一个进程里面默认有一个主线程。由主线程去启动子线程。

    1.多线程

    import threading,time
    def run():
        time.sleep(3) #干活需要3s
        print('哈哈哈')
    #########################################
    for i in range(5): #串行
        run()
    #########################################
    for i in range(5):  #并行,多线程, 就是N个线程一起在干活
        t = threading.Thread(target=run) #实例化了一个线程
        t.start()
    #########################################

    2.多线程等待

    举个栗子:我们定义一个urls字典,然后用并行和串行分别扒一下这些url上的内容,并统计时间。

    urls = {
        'besttest':'http://www.besttest.cn',
        'niuniu':'http://www.nnzhp.cn',
        'dsx':'http://www.imdsx.cn',
        'cc':'http://www.cc-na.cn',
        'alin':'http://limlhome.cn'
    }

    需要定义一个扒网页内容的函数,如果后面需要统计每个子线程的耗时,那么就需要在这个函数中定义start_time和end_time,函数如下:

    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

    所有的代码如下:

    import requests,time,threading
    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
    threads = []
    start_time = time.time()
    for k,v in  urls.items():   #5次
        t = threading.Thread(target=down_html,args=(k,v)) #多线程的函数如果传参的话,必须得用args
        t.start()
        threads.append(t)
    #6个线程
    #进程里面默认有一个线程,这个线程叫做主线程
    for t in threads:
        t.join()    #多线程等待,主线程循环等待5个子线程执行结束
    
    end_time = time.time()
    run_time = end_time - start_time
    print(data)
    print('下载总共花了xxx时间',run_time)

    3.守护线程

    import threading,time
    def run():
        time.sleep(3)
        print('哈哈哈')
    for i in range(50): t = threading.Thread(target=run) t.setDaemon(True) #把子线程设置成为守护线程 t.start() print('Done,运行完成。')
    #当主线程运行完成后就立即结束子线程。所以运行结果只输出了“Done,运行完成”。子线程并没有来得及打印“哈哈哈”就被结束了。

    4.线程锁

    import threading,time
    num = 1
    lock = threading.Lock()  #申请一把锁
    
    def run():
        time.sleep(1)
        global num
        lock.acquire() #加锁
        num+=1
        lock.release() #解锁
    ts = []
    for i in range(100):
        t = threading.Thread(target=run)
        t.start()
        ts.append(t)
    [t.join() for t in ts]   #列表生成式,多线程等待
    print(num)

    5.多进程和多进程等待

    import multiprocessing,threading
    def my():
        print('哈哈哈')
    
    def run(num):
        for i in range(num):   #启动num个线程
            t = threading.Thread(target=my)
            t.start()
    if __name__ == '__main__':
        for i in range(5):   #启动5个进程
            p = multiprocessing.Process(target=run,args=(6,))  #启动一个进程,如果参数只有一个,那么参数后面一定要加一个逗号
            p.start()
    
    # 进程5个
        # 每个进程下启动6个线程
    #进程等待也可以用pjoin()

    总结:

          1、如果子线程运行的函数里面有返回值该怎么处理?

              如果子线程运行的函数里面有返回值,是不能获取到的,只能在外面定义一个list或字典来存放每次处理的结果。

          2、电脑有几核就能同时运行几个线程。但是,python的多线程只能利用一个CPU的核心。

          3、锁,在多线程同时修改一个数据或文件的时候,可能会把数据覆盖,在python2里面需要加锁,python3里面不加锁也无所谓,默认会自动帮你加锁。

         4.守护线程,只要主线程结束,那么子线程立即结束,不管子线程有没有运行完成。

         5、多进行,多用于处理CPU密集型任务;多线程,多用于IO密集型任务。

  • 相关阅读:
    类型转换
    希尔排序
    冒泡排序
    More Effective C++ (静态绑定与动态类型)
    More Effective C++ (限制类的对象数量)
    算法复杂度
    交换两个数的方法
    QString类(常用函数)
    面向过程与面向对象
    QTableWidget控件总结
  • 原文地址:https://www.cnblogs.com/mululu/p/9118411.html
Copyright © 2011-2022 走看看