国外时尚设计网站,不属于网站建设方式的是,网站首页布局的设计,多用户网上商城多线程和多进程的快速入门
学习自#xff1a;莫烦Python www.mofanpy.com
Threading - 多线程运算python程序
多线程的简单理解#xff1a;把数据分成很多段#xff0c;将每一段数据放入一个线程#xff0c;将所有的线程同时开始#xff0c;大大的节省了运算时间。相…多线程和多进程的快速入门
学习自莫烦Python www.mofanpy.com
Threading - 多线程运算python程序
多线程的简单理解把数据分成很多段将每一段数据放入一个线程将所有的线程同时开始大大的节省了运算时间。相当于请一个人来工作一件事和请很多人来工作一件事
Threading 可以分配python分批量在同一时间做事情但是Threading只能是在一个py脚本中
添加一个线程的案例
import threading#def main():
# print(threading.active_count()) # 查看现在激活线程的数量
# print(threading.enumerate()) # 查看当前的threading都是什么
# print(threading.current_thread()) # 查看我运行这个函数程序的时候 对应的threading是什么def thread_job():print(This is a thread of %s % threading.current_thread()) # 查看我运行这个函数程序的时候 对应的threading是什么def main():thread threading.Thread(targetthread_job,) # 添加线程 这个线程做什么由target指定thread.start() # 添加一个线程后要启动线程才能让这个线程开始工作if __name__ __main__:main()程序运行的结果为
This is a thread of Thread(Thread-1, started 6300)threading中的join的功能
由于多线程是同石进行运行的线程任务如果某些时刻你想等待所有的线程都运行完然后开始某些操作这个时候需要在这个操作前对每个线程使用join操作
join操作是等待threading线程运行完
import threading
import time
def thread_job():print(T1 start\n)for i in range(10): time.sleep(0.1) # 睡一秒 print(T1 finish\n)def T2_job():print(T2 start\n)print(T2 finish\n)def main():added_thread threading.Thread(targetthread_job, nameT1) # name为给线程命名thread2 threading.Thread(targetT2_job, nameT2)added_thread.start()thread2.start()thread2.join()added_thread.join()print(all done\n)if __name__ __main__:main()不加join的结果如下
T1 startT2 start
all doneT2 finishT1 finish加join的结果如下
T1 startT2 startT2 finishT1 finishall done多线程搭配Queue功能
多线程无返回值所以要把运算出来的结果放在一个长的队列中对每一个线程的队列到主线程中拿出来以便做继续的运算。
import threading
import time
from queue import Queuedef job(l,q):# 对每一个列表中的值做平方运算for i in range(len(l)):l[i] l[i]**2q.put(l)def multithreading():q Queue() # 定义队列threads [] # 用来存储所有的线程data [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]for i in range(4): # 定义四个线程 计算大列表中的四个小列表t threading.Thread(targetjob, args(data[i], q)) # args用来给线程 传递参数t.start() # 启动线程threads.append(t) # 将每个小列表的计算线程 存储到线程列表中for thread in threads: thread.join() # 等到所有的线程运行完 再继续操作results []for _ in range(4): results.append(q.get()) # 将每个线程运算的结果 保存print(results)if __name__ __main__:multithreading()该程序的结果如下
[[1, 4, 9], [9, 16, 25], [16, 16, 16], [25, 25, 25]]多线程的效率分析
多线程的全局控制并不是把任务平均的分配个每一个线程 python只能让一个线程在某一时刻运算一个东西然后不停的切换线程让你误以为这些线程是在相同时刻在运算。 学过操作系统应该会很容易理解多线程的并发运算
下面实力代码中
normal方法对四倍的l列表执行累加运算
multithreading多线程方法将四倍的l列表分为四份用四个多线程同时处理
import threading
from queue import Queue
import copy
import timedef job(l, q):res sum(l)q.put(res)def multithreading(l):q Queue()threads []for i in range(4):t threading.Thread(targetjob, args(copy.copy(l), q), nameT%i % i)t.start()threads.append(t)[t.join() for t in threads]total 0for _ in range(4):total q.get()print(total)def normal(l):total sum(l)print(total)if __name__ __main__:l list(range(1000000))s_t time.time()normal(l*4)print(normal: ,time.time()-s_t)s_t time.time()multithreading(l)print(multithreading: , time.time()-s_t)程序的执行结果
1999998000000
normal: 0.08538269996643066
1999998000000
multithreading: 0.08719158172607422用了多线程比未用多线程的耗时反而多了
多线程与lock锁
锁的用法当第一个线程处理完这一批数据得到一个初步的结果然后再把这个结果拿去给第二个线程处理这个时候就需要锁住第一个线程等他处理完再开始第二个线程
在要进行上锁的程序的前后设置锁
import threadingdef job1():global A, locklock.acquire() # 在要进行上锁的程序前 设置锁for i in range(10): # 对A进行10次累加1A 1print(job1, A)lock.release() # 在要进行上锁的程序后 设置锁def job2():global A, locklock.acquire()for i in range(10): # 对A进行10次累加10A 10print(job2, A)lock.release()if __name__ __main__:lock threading.Lock() # 定义锁A 0 # 定义一个全局变量 模拟共享内存t1 threading.Thread(targetjob1)t2 threading.Thread(targetjob2)t1.start()t2.start()t1.join()t2.join()不加锁的程序结果: 两个线程同时运行结果上为交替对A进行操作
job1 1
job1 2
job1 13
job2 12
job1 14
job2 24
job1 25
job2 35
job1 36
job2 46
job1 47
job2 57
job1 58
job2 68
job1 69
job2 79
job1 80
job2 90
job2 100
job2 110加锁的程序结果 job1先上锁 待程序运行完后 解锁。此时job2再上锁 待程序运行完后 解锁
job1 1
job1 2
job1 3
job1 4
job1 5
job1 6
job1 7
job1 8
job1 9
job1 10
job2 20
job2 30
job2 40
job2 50
job2 60
job2 70
job2 80
job2 90
job2 100
job2 110Multiprocessing - 多进程运算python程序
运用多核CPU处理器CPU运算python程序一般只会用一个核来处理程序但是现代计算器的处理器一般都是多核如果不用白白的浪费可以将其运用起来加速程序的处理。
多线程实际上还是同一个时间处理一个线程并发轮转调度而多核完全避免了这种情况它会把任务平均分配给每一个核每一个核都有单独的运算空间和运算能力多核从一定程度上避免了多线程劣势。创建进程
import multiprocessing as mpdef job(q):print(进程创建, q)if __name__ __main__:p1 mp.Process(targetjob, args(q,))p1.start()进程与Queue输出
将每一个核运算出来的结果放入到队列Queue中等到所有的核运算完成后再将结果从队列中取出以便后续操作
import multiprocessing as mpdef job(q):res 0for i in range(1000):res ii**2i**3q.put(res) # 将运算后的值操作放入到队列if __name__ __main__:q mp.Queue() # 定义队列p1 mp.Process(targetjob, args(q,)) # 注意args 即使只有一个参数 也要写成(q,) 不然会报错 p2 mp.Process(targetjob, args(q,))p1.start()p2.start()p1.join()p2.join()res1 q.get() # 从队列中获取值res2 q.get()print(res1res2)运行结果为499667166000
进程池
进程池就是把所有要运行的东西放到一个池子里python自己解决如何分配这些进程如何分配运行出来的结果。
import multiprocessing as mpdef job(x): # 平方操作return x*xdef multicore():pool mp.Pool(processes2) # 默认的是你所有的核心 processes是指定想用的核的数量res pool.map(job, range(10)) # map 将range(10) 交给job并将结果返回print(res)res pool.apply_async(job, (2,)) # 只传入一个值给job 如果输入的是(2,345)会报错因为只能传入一个值print(res.get()) # 使用get获取multi_res [pool.apply_async(job, (i,)) for i in range(10)] # 利用迭代器 获取对多个值操作的结果print([res.get() for res in multi_res]) # 利用列表迭代获取if __name__ __main__:multicore()程序运行的结果
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
4
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]多进程使用shared memory共享内存
为什么使用共享内存不用全局变量
因为多进程中传入全局变量给每个cpu多进程对全局变量进行操作后传给其它进程是行不通的
import multiprocessing as mpvalue mp.Value(i, 1) # i是整数 d是double小数 f是float小数等等
array mp.Array(i, [1, 2, 3, 4]) # 只能是一维列表不能是多维value和array可以被每一个核读取加载到内存
多进程与lock锁
锁的应用
import multiprocessing as mp
import timedef job(v, num, l):l.acquire()for _ in range(10):time.sleep(0.1)v.value numprint(v.value)l.release()def multicore(): l mp.Lock() # 实例化锁v mp.Value(i, 0) # 设立共享内存变量p1 mp.Process(targetjob, args(v, 1, l)) p2 mp.Process(targetjob, args(v, 3, l))p1.start()p2.start()p1.join()p2.join()if __name__ __main__:multicore()加锁的结果为
前面程序依次1 后面程序依次3
不加锁的结果为
3 4 7 8 11 12这样两个多进程交替打印结果
多线程、多进程以及函数的效率对比
import multiprocessing as mp
import threading as td
import timedef job(q):res 0for i in range(1000000):res ii**2i**3q.put(res) # queuedef multicore():q mp.Queue()p1 mp.Process(targetjob, args(q,))p2 mp.Process(targetjob, args(q,))p1.start()p2.start()p1.join()p2.join()res1 q.get()res2 q.get()print(multicore: , res1res2)def normal():res 0for _ in range(2):for i in range(1000000):res ii**2i**3print(normal:, res)def multithread():q mp.Queue()t1 td.Thread(targetjob, args(q,))t2 td.Thread(targetjob, args(q,))t1.start()t2.start()t1.join()t2.join()res1 q.get()res2 q.get()print(multithread:, res1res2)if __name__ __main__:st time.time()normal()st1 time.time()print(normal time:, st1 - st)multithread()st2 time.time()print(multithread time:, st2 - st1)multicore()print(multicore time:, time.time()-st2)运行的结果
# 不用进程和线程
normal: 499999666667166666000000
normal time: 0.75795578956604
# 多线程
multithread: 499999666667166666000000
multithread time: 0.7419922351837158
# 多进程
multicore: 499999666667166666000000
multicore time: 0.4487142562866211多进程运算的时间明显由于另外两个多线程的运算与什么都不做时间差不多说明多线程对于某些运算还是存在明显的短板