windows:python
当建立进程时,会将当前py文件由上到下从新执行一次,因此咱们要将执行代码放在__ main __ 中。linux
linux:程序员
在linux系统中,会直接复制一分代码去执行windows
这里有解决问题的办法:
国内:开源中国,CSDN, cnblods,https://www.v2ex.com/安全
国外:Stack Overflow多线程
GIL: 全局解释器锁并发
Cpython的内存管理不是线程安全,在同一进程开启的多线程,同一时刻只能有一个线程执行,没法利用多核优点函数
GIL全局解释锁,本质上就是一把互斥锁,保证数据的安全spa
GIL全局解释器的优缺点:操作系统
1.优势:
保证数据的安全
2.缺点:
单个进程下,开启多个线程,牺牲执行效率,没法实现并行,只能实现并发
,只能实现并发。
IO密集型,多线程
计算密集型,多进程
io密集型任务,每一个任务4s
单核:
开启的线程比进程节省资源
多核:
多线程:
开启4个子线程:16s
多进程:
开启4个进程:16s + 申请开启资源消耗的时间
计算密集型任务,每一个任务4s
单核:
开启线程比进程节省资源
多核:
多线程:
开启4个子线程:16s
多进程:
开启多个进程:4s
什么是协程?
进程:资源单位
线程:执行单位
协程: 单线程下实现并发
在io密集的状况下,使用协程能提升最高效率
ps:协程不是任何单位,只是一个个程序员臆想出来的东西
协成的目的是为了:
手动实现‘遇到io切换+保存状态’去欺骗操做系统,让操做系统误觉得没有io操做,将cpu的执行权限给你
from gevent import monkey # 猴子补丁 monkey.patch_all() # 监听全部的任务是否有io操做 from gevent import spawn # 任务 from gevent import joinall import time def task1(): print('start from task1...') time.sleep(1) print('end from task1...') def task2(): print('start from task2...') time.sleep(2) print('end from task2...') def task3(): print('start from task3...') time.sleep(3) print('end from task3...') if __name__ == '__main__': start_time = time.time() sp1 = spawn(task1) sp2 = spawn(task2) sp3 = spawn(task3) # sp1.start() # sp2.start() # sp3.start() # sp1.join() # sp2.join() # sp3.join() joinall([sp1, sp2, sp3]) end_time = time.time() print(f'消耗时间:{end_time - start_time}') start from task1... start from task2... start from task3... end from task1... end from task2... end from task3... 消耗时间:3.0070078372955322
线程池与进程池中的回调函数的使用: # from gevent import monkey;monkey.patch_all() # from gevent import spawn # import time # # # def task1(name): # print(name) # print('start') # time.sleep(1) # print('end') # # # def task2(): # print('start') # time.sleep(3) # print('end') # # # def task3(): # print('start') # time.sleep(5) # print('end') # # if __name__ == '__main__': # spawn(task1, 'tank') # spawn(task2) # g = spawn(task3) # g.join() # 线程池与进程池 # 进程池 # from concurrent.futures import ProcessPoolExecutor # import time # # 池子对象: 内部能够帮你提交50个启动进程的任务 # p_pool = ProcessPoolExecutor(50) # # # def task1(n): # print(f'from task1...{n}') # time.sleep(10) # # # if __name__ == '__main__': # n = 1 # while True: # # 参数1: 函数名 # # 参数2: 函数的参数1 # # 参数3: 函数的参数2 # # submit(参数1, 参数2, 参数3) # p_pool.submit(task1, n) # n += 1 # 线程池 # from concurrent.futures import ThreadPoolExecutor # import time # # 池子对象: 内部能够帮你提交50个启动进程的任务 # p_pool = ThreadPoolExecutor(50) # # # def task1(n): # print(f'from task1...{n}') # time.sleep(10) # # # if __name__ == '__main__': # n = 1 # while True: # # 参数1: 函数名 # # 参数2: 函数的参数1 # # 参数3: 函数的参数2 # # submit(参数1, 参数2, 参数3) # p_pool.submit(task1, n) # n += 1 # add_done_callback # from concurrent.futures import ThreadPoolExecutor # import time # # 池子对象: 内部能够帮你提交50个启动进程的任务 # p_pool = ThreadPoolExecutor(50) # # # def task1(n): # print(f'from task1...{n}') # time.sleep(5) # return 'tank' # # # def get_result(obj): # # print(obj.__dict__) # # print(obj._result) # result = obj.result() # print(result) # # # if __name__ == '__main__': # n = 1 # while True: # # 参数1: 函数名 # # 参数2: 函数的参数1 # # 参数3: 函数的参数2 # # submit(参数1, 参数2, 参数3) # # add_done_callback(参数1),会将submit提交的task1执行的结果,传给get_result中的第一个参数,第一个参数是一个对象。 # p_pool.submit(task1, n).add_done_callback(get_result) # n += 1