You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
6.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 多任务介绍
什么是多任务?
操作系统可以同时执行多个任务
现在的操作系统:windows mac linux unix
这些操作系统 都支持多任务
单核CPU如何实现多任务
表面看,每个任务都是同时执行,实际上是每个任务在轮询着执行,只是因为CPU的调度太快导致我们感觉像是所有任务都在同时执行
多核CPU如何实现多任务?
是真正实现了多个任务同时执行
并发看上去一起执行任务数大于CPU核心数
并行一起执行任务数必须小于等于CPU核心数
实现多任务的方式:
1、多进程方式
2、多线程方式
3、协程方式
4、多进程+多线程
### 没有多进程
```python
import time
def func():
while True:
print("this is a process2")
time.sleep(1.5)
if __name__ == '__main__':
while True:
print("this is a process1")
time.sleep(1)
func()
```
### multiprocessing 多进程
```python
from multiprocessing import Process
import time,os
def func(str):
#os.getpid 获取当前进程的进程号
#os.getppid 获取当前进程的父进程
while True:
print("this is process 2--%s--%s--%s"%(str,os.getpid(),os.getppid()))
time.sleep(1.5)
if __name__ == '__main__':
print("父进程启动...--%s--%s"%(os.getpid(),os.getppid()))
# 创建子进程
# target 说明进程的任务
p = Process(target=func,args=("python",))
# 启动进程
p.start()
# 主进程中的
while True:
print("this is a process 1--%s--%s"%(os.getpid(),os.getppid()))
time.sleep(1)
```
### 让父进程等待子进程结束之后父进程再结束
```python
from multiprocessing import Process
from time import sleep
def func():
print("子进程启动...")
sleep(3)
print("子进程结束...")
if __name__ == '__main__':
print("父进程启动...")
p = Process(target = func)
p.start()
# sleep(1)
# 让父进程等待子进程结束之后父进程再结束
# timeout 超时时间 父进程的等待时间
p.join()
#执行后一直等待
print("父进程结束...")
```
### 在子进程中修改全局变量 对父进程中的全局变量没有影响
```python
from multiprocessing import Process
num = 100
def run1():
print("孙子进程开始...")
print("孙子进程结束...%s"%(num))
def run():
print("子进程开始...")
global num
num += 1
print(num)
p = Process(target=run1)
p.start()
p.join()
print("子进程结束...")
if __name__ == '__main__':
print("父进程开始...")
p = Process(target=run)
p.start()
p.join()
num += 2
# 在子进程中修改全局变量 对父进程中的全局变量没有影响
# 我们在创建子进程的时候 对全局变量做了一个备份
# 子进程和父进程的Num是两个完全不同的变量
# 所有进程对全局变量的修改 都不会影响其它进程
print("父进程结束...%d"%(num))
```
### 进程池
```python
from multiprocessing import Pool,Process
import time,random
def foo():
print("孙子进程开始...")
print("孙子进程结束...")
def func(__name__):
print("子进程%s启动..."%(__name__))
start = time.time()
time.sleep(random.choice([1,2,3]))
end = time.time()
print("子进程%s结束...耗时%.2f"%(__name__,end - start))
if __name__ == '__main__':
print("父进程开始...")
# 创建进程池
# 如果没有参数 默认大小为自己电脑的CPU核心数
# 表示可以同时执行的进程数量
pp = Pool(2)
for i in range(4):
# 创建进程,放入进程池统一管理
pp.apply_async(func,args=(i,))
# 在调用join之前必须先关掉进程池
# 进程池一旦关闭 就不能再添加新的进程了
pp.close()
# 进程池对象调用join,会等待进程池中所有的子进程结束之后再结束父进程
pp.join()
print("父进程结束...")
```
# 多线程:
在一个进程内部,要同时干很多事,就需要同时执行多个子任务
那么我们把进程内的这些子任务叫做线程
线程的内存空间是共享的 每个线程都共享同一个进程的资源
模块:
1、_thread模块 低级模块
2、threading模块 高级模块 对_thread模块进行了封装
"""
### 创建线程
```python
import threading,time
def run(num):
print("子线程%s开始..."%(threading.current_thread().__name__))
time.sleep(2)
print(num)
time.sleep(2)
# current_thread 返回一个当前线程的实例
print("子线程%s结束..."%(threading.current_thread().__name__))
if __name__ == '__main__':
print("主线程%s启动..."%(threading.current_thread().__name__))
# 创建子线程
t = threading.Thread(target = run,args = (1,))
t.start()
t.join()
print("主线程%s结束..."%(threading.current_thread().__name__))
```
### 多线程共享资源
```python
import threading
num = 0
var = 0
def run(n):
global num
for i in range(1000000):
num += n
num -= n
def run1(n):
global var
for i in range(100):
var += n
var -= n
if __name__ == '__main__':
t1 = threading.Thread(target=run,args=(6,))
t2 = threading.Thread(target=run,args=(9,))
t3 = threading.Thread(target=run,args=(5,))
t3.start()
t1.start()
t2.start()
t1.join()
t2.join()
t3.join()
print("num = %s"%(num))
```
### 互斥锁
```python
import threading
创建锁对象
lock = threading.Lock()
num = 0
def run(n):
global num
for i in range(1000000):
# 加锁 为了确保下面代码只能由一个线程从头到尾的执行
# 会阻止多线程的并发执行,所以效率会大大降低
"""
lock.acquire()
try:
num = num - n
num = num + n
finally:
# 解锁
lock.release()
"""
with lock:
num = num + n
num = num - n
if __name__ == '__main__':
t1 = threading.Thread(target=run,args=(6,))
t2 = threading.Thread(target=run,args=(9,))
t1.start()
t2.start()
t1.join()
t2.join()
print("num = %s"%(num))
```