python学习笔记-day10-【多进程,多线程】

开始使用Pyton的多进程,多线程。

一、多线程,多线程的概念

多线程、多进程
        1、线程是程序里面最小的执行单元。
        2、进程是资源的集合。
            线程是包含在一个进程里面的, 一个进程可以有多个线程。
            一个进程里面默认有一个线程。

        主线程
            默认有个主线程
         子线程:
            主线程启动子线程

多进程
多用于处理CPU密集型任务
多线程
多用于IO密集型任务
Input Ouput

二、多线程

1、多线程示例1, 多线程时没有计算总共花了多少时间

import threading,time

def run():
    time.sleep(3) #干活需要3秒
    print('哈哈哈')

for i in range(5): #串行,总共需要15秒
    run()

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

#多线程,就是N个线程一起干活

2、多线程示例2,显示如何计算多线程时,总共的时间消耗

urls = {
    'baidu':'http://www.baidu.com',
    'niu':'http://www.nnzhp.cn',
    'dsx':'http://www.imdsx.cn',
    'cc':'http://www.cc-na.cn'
}

import requests,time
import threading,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  #计算每个线程时间
    # print(end_time-start_time, url)
    data[url] = run_time

#1、串行
#统计一下时间
start_time = time.time()
for key, value in urls.items():
    down_html(key, value)
end_time = time.time()
run_time = end_time - start_time
print('下载总共花的时间', run_time)
#下载总共花的时间 37.91216850280762

#2、并行
threads = []
start_time = time.time()
for key,value in urls.items():
    #多线程的函数如果要传参的话,必须得调用atgs
    t = threading.Thread(target=down_html, args=(key,value))
    t.start()
    threads.append(t)

for t in threads:  #让主线程等待所有子线程结束
    t.join()
#6个线程
#进程里面默认有一个线程,这个线程叫主线程
end_time = time.time()
run_time = end_time - start_time

print('下载总共花的时间', run_time)
print(data)

3、线程总结

1、如果这个函数里面有返回值的话,怎么获取呢?
   子线程运行的函数,如果里面有返回值的话,是不能获取到的
   只能在外面定义一个list或者字典来存每次处理的结果。
   电脑CPU有几核,那么只能同时运行几个线程。
   但是呢,python的多线程,只能利用一个CPU的核心。
   GIL 全局解释器锁。

三、线程锁

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

1、线程锁示例用法

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(50):
    t = threading.Thread(target=run)
    t.start()
    ts.append(t)

[t.join() for t in ts] #列表生成式 #主线程等待子线程结束
print(num)

四、守护线程

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

1、守护线程示例用法

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, 运行完成.')  #主线程运行到此,就退出了,子线程都没有运行结束,这就是守护线程。

五、线程等待

1、就是主线程等待子线程运行完成后才退出主程序

2、线程等待示例

import threading,time

def run():
    time.sleep(3) #干活需要3秒
    print('哈哈哈')

start_time = time.time()
threads = []
for i in range(5):
    t = threading.Thread(target=run)
    t.start()
    threads.append(t)
    # t.join() #主线程等待子线程执行结束
print(threads)
for t in threads: #主线程循环等待5个子线程执行结束
    t.join()#循环等待
end_time = time.time()

print('run_time: ', end_time-start_time)

六、多进程

1、多进程包含多线程示例

import multiprocessing,threading

def my():
    print('哈哈哈')


def run(num):
    for i in range(num):
        t = threading.Thread(target=my)  #进程里的多线程
        t.start()
        # print('哈哈哈哈')

if __name__== '__main__':
    for p in range(5):
        p = multiprocessing.Process(target=run,args=(6,)) #启动一个进程,只有一个参数的时候,要加一个,
        p.start()  #多进程的启动方式,需要在__name__下才能启动

#进程5个
   #每个进程6个线程

猜你喜欢

转载自www.cnblogs.com/shmily2018/p/9094669.html