1. 进程是资源分配最小单位
2. 当一个可执行程序被系统执行(分配内存等资源)就变成了一个进程
进程定义拓展回答内容
多道编程概念
from multiprocessing import Process,Pool
import time,os
def foo(i):
time.sleep(2)
print("in the process",os.getpid()) #打印子进程的pid
return i+100
def call(arg):
print('-->exec done:',arg,os.getpid())
if __name__ == '__main__':
pool = Pool(3) #进程池最多允许5个进程放入进程池
print("主进程pid:",os.getpid()) #打印父进程的pid
for i in range(10):
#用法1 callback作用是指定只有当Foo运行结束后就执行callback调用的函数,父进程调用的callback函数
pool.apply_async(func=foo, args=(i,),callback=call)
#用法2 串行 启动进程不在用Process而是直接用pool.apply()
# pool.apply(func=foo, args=(i,))
print('end')
pool.close() #关闭pool
pool.join() #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
import threading
import time
def sayhi(num): #定义每个线程要运行的函数
print("running on number:%s" %num)
time.sleep(3)
for i in range(50):
t = threading.Thread(target=sayhi,args=('t-%s'%i,))
t.start()
import threading
import time
start_time = time.time()
def sayhi(num): #定义每个线程要运行的函数
print("running on number:%s" %num)
time.sleep(3)
t_objs = [] #将进程实例对象存储在这个列表中
for i in range(50):
t = threading.Thread(target=sayhi,args=('t-%s'%i,))
t.start() #启动一个线程,程序不会阻塞
t_objs.append(t)
print(threading.active_count()) #打印当前活跃进程数量
for t in t_objs: #利用for循环等待上面50个进程全部结束
t.join() #阻塞某个程序
print(threading.current_thread()) #打印执行这个命令进程
print("----------------all threads has finished.....")
print(threading.active_count())
print('cost time:',time.time() - start_time)
import threading
import time
start_time = time.time()
def sayhi(num): #定义每个线程要运行的函数
print("running on number:%s" %num)
time.sleep(3)
for i in range(50):
t = threading.Thread(target=sayhi,args=('t-%s'%i,))
t.setDaemon(True) #把当前线程变成守护线程,必须在t.start()前设置
t.start() #启动一个线程,程序不会阻塞
print('cost time:',time.time() - start_time)
作用:在一个进程内,同一时刻只能有一个线程执行
说明:python多线程中GIL锁只是在CPU操作时(如:计算)才是串行的,其他都是并行的,所以比串行快很多
import time
import threading
lock = threading.Lock() #1 生成全局锁
def addNum():
global num #2 在每个线程中都获取这个全局变量
print('--get num:',num )
time.sleep(1)
lock.acquire() #3 修改数据前加锁
num -= 1 #4 对此公共变量进行-1操作
lock.release() #5 修改后释放
import requests
from concurrent.futures import ThreadPoolExecutor
def fetch_request(url):
result = requests.get(url)
print(result.text)
url_list = [
'https://www.baidu.com',
'https://www.google.com/', #google页面会卡住,知道页面超时后这个进程才结束
'http://dig.chouti.com/', #chouti页面内容会直接返回,不会等待Google页面的返回
]
pool = ThreadPoolExecutor(10) # 创建一个线程池,最多开10个线程
for url in url_list:
pool.submit(fetch_request,url) # 去线程池中获取一个线程,线程去执行fetch_request方法
pool.shutdown(True) # 主线程自己关闭,让子线程自己拿任务执行
协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上线程阻塞(Blocking)操作(如IO时)会阻塞掉整个程序
注:Gevent只用起一个线程,当请求发出去后gevent就不管,永远就只有一个线程工作,谁先回来先处理
import gevent
import requests
from gevent import monkey
monkey.patch_all()
# 这些请求谁先回来就先处理谁
def fetch_async(method, url, req_kwargs):
response = requests.request(method=method, url=url, **req_kwargs)
print(response.url, response.content)
# ##### 发送请求 #####
gevent.joinall([
gevent.spawn(fetch_async, method='get', url='https://www.python.org/', req_kwargs={}),
gevent.spawn(fetch_async, method='get', url='https://www.google.com/', req_kwargs={}),
gevent.spawn(fetch_async, method='get', url='https://github.com/', req_kwargs={}),
])