我奶奶都能看懂系列016Python进程和线程的使用
Posted 毛毛是一只狗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我奶奶都能看懂系列016Python进程和线程的使用相关的知识,希望对你有一定的参考价值。
🌌 专注Golang,Python语言,云原生,人工智能领域得博主;
💜 过去经历的意义在于引导你,而非定义你;
📢 欢迎点赞 👍 收藏 ⭐留言!
Python进程和线程的使用
01-多进程的使用
# 1. 导包
import multiprocessing
import time
# 2.1 定义任务函数 唱歌
def sing():
# 循环只执行了 5 次,在一个时间片内就执行结束了
for i in range(5):
print('正在唱歌.....')
# 执行一次唱歌之后,代码实现,手动的失去 CPU,切换任务, time.sleep()
time.sleep(0.1) # 让程序休眠 0.1秒, 进程会进入阻塞态,失去 CPU
# 2.2 跳舞
def dance():
for i in range(5):
print('正在跳舞....')
time.sleep(0.1)
if __name__ == '__main__':
# 2. 创建进程对象
# target 参数指定进程执行的任务,参数需要是函数, 并且是函数名, 不能加括号,
process_1 = multiprocessing.Process(target=sing) # 创建进程,分配任务,sing
process_2 = multiprocessing.Process(target=dance) # 创建进程,分配任务,sing
# 3. 启动的进程, 相当于是让进程处于就绪态,等待 CPU 分配时间
process_1.start()
process_2.start()
02-获取进程编号
# 1. 导包
import multiprocessing
import time
import os
# 2.1 定义任务函数 唱歌
def sing():
# 循环只执行了 5 次,在一个时间片内就执行结束了
print('sing:', multiprocessing.current_process(), multiprocessing.current_process().pid) # process-1
# os.getpid 获取当前进程的 id os.getppid() 获取父进程的 id
print(f'sing, pid os.getpid(), ppidos.getppid()')
for i in range(5):
print('正在唱歌.....')
# 执行一次唱歌之后,代码实现,手动的失去 CPU,切换任务, time.sleep()
time.sleep(0.1) # 让程序休眠 0.1秒, 进程会进入阻塞态,失去 CPU
os.kill(os.getpid(), 9) # 杀死当前进程,
# 2.2 跳舞
def dance():
print('dance:', multiprocessing.current_process(), multiprocessing.current_process().pid) # process-2
print(f'dance, pid os.getpid(), ppidos.getppid()')
for i in range(5):
print('正在跳舞....')
time.sleep(0.1)
if __name__ == '__main__':
# 程序启动,默认会有一个进程,主进程
# 2. 创建进程对象
# target 参数指定进程执行的任务,参数需要是函数, 并且是函数名, 不能加括号,
# 进程对象.name 获取进程的名字, 进程对象.pid 能够获取进程对象的进程 id
# multiprocessing.current_process() 获取当前的进程对象
print('main:', multiprocessing.current_process(), multiprocessing.current_process().pid) # 主进程执行
print(f'main, pid os.getpid(), ppidos.getppid()')
process_1 = multiprocessing.Process(target=sing) # 创建进程,分配任务,sing
process_2 = multiprocessing.Process(target=dance) # 创建进程,分配任务,sing
# 3. 启动的进程, 相当于是让进程处于就绪态,等待 CPU 分配时间
process_1.start()
process_2.start()
03-进程传参
# 1. 导包
import multiprocessing
import time
# 2.1 定义任务函数 唱歌
def sing(singer, song):
# 循环只执行了 5 次,在一个时间片内就执行结束了
for i in range(5):
print(f'singer正在唱song.....')
# 执行一次唱歌之后,代码实现,手动的失去 CPU,切换任务, time.sleep()
time.sleep(0.1) # 让程序休眠 0.1秒, 进程会进入阻塞态,失去 CPU
# 2.2 跳舞
def dance(dancer, name):
for i in range(5):
print(f'dancer正在跳name_____________')
time.sleep(0.1)
if __name__ == '__main__':
# 2. 创建进程对象
# 由于进程执行的任务函数,sing 和 dance 都有形参,所有在创建对象的时候需要传递实参
# 方式一, args 形参, 实参值需要是元组类型,
process_1 = multiprocessing.Process(target=sing, args=('毛不易', '消愁')) # 创建进程,分配任务,sing
# 方式二, kwargs 形参, 实参值需要是字典,字典的 key 是任务函数的形参名,
process_2 = multiprocessing.Process(target=dance,
kwargs='dancer': '罗老师', 'name': '精武门') # 创建进程,分配任务,sing
# 3. 启动的进程, 相当于是让进程处于就绪态,等待 CPU 分配时间
process_1.start()
process_2.start()
04-进程不共享全局变量
# 1. 导包
import multiprocessing
import time
# 定义全局变量
g_list = []
# 2.1 定义进程执行的任务函数
def write_data():
for i in range(5):
g_list.append(i)
print('添加数据成功', i)
# 代码执行到此,代表 5 个数据添加完成
print(f"write_data: g_list")
def read_data():
print(f"read: g_list")
if __name__ == '__main__':
# g_list = []
# 2. 创建进程对象
write_process = multiprocessing.Process(target=write_data)
read_process = multiprocessing.Process(target=read_data)
# 3. 启动进程
write_process.start()
write_process.join() # 1. 主进程阻塞等待 2. 等等待write_process 执行完成
read_process.start()
# 需求: 主进程在最后打印 g_list 值
# 解决方案: 使用 进程对象.join() 方法, 阻塞等待进程执行完成
# 1. 谁阻塞等待, 这行代码写在哪,哪个进程就阻塞等待
# 2. 等待谁执行完成, 哪个对象调用这个方法,就是等待哪个对象执行完成
print(f"main: g_list")
05-主进程会会等待子进程结束再结束
import multiprocessing
import time
def func():
for i in range(5):
print('子进程', i)
time.sleep(0.5) # 子进程至少需要 2.5 秒才能结束
print('子进程代码结束,即活干完了')
if __name__ == '__main__':
sub_process = multiprocessing.Process(target=func)
sub_process.start()
time.sleep(1) # 主进程至少需要 1 秒结束
print('主进程的代码结束, 即活干完了') # 主进程结束,程序就结束了
06-让子进程随着主进程的结束而结束
import multiprocessing
import time
import sys
def func():
for i in range(5):
print('子进程', i)
time.sleep(0.5) # 子进程至少需要 2.5 秒才能结束
print('子进程代码结束,即活干完了')
if __name__ == '__main__':
sub_process = multiprocessing.Process(target=func)
# 方案二 将子进程对象设置为 daemon 进程
# sub_process.daemon = True # 修改对象的属性
sub_process.start()
time.sleep(1) # 主进程至少需要 1 秒结束
print('主进程的代码结束, 即活干完了') # 主进程结束,程序就结束了
# 主进程结束了,想让子进程一块结束,
# 方案一
# sub_process.terminate() # 终止子进程的执行
# exit() # 让进程退出
sys.exit()
07-多线程的使用
# 1. 导包
import threading
import time
# 2.1 定义任务函数 唱歌
def sing():
print("sing", threading.current_thread().name)
# 循环只执行了 5 次,在一个时间片内就执行结束了
for i in range(5):
print('正在唱歌.....')
time.sleep(0.1) # 让程序休眠 0.1秒, 进程会进入阻塞态,失去 CPU
# 2.2 跳舞
def dance():
print("dance", threading.current_thread().name)
for i in range(5):
print('正在跳舞....')
time.sleep(0.1)
if __name__ == '__main__':
# 2. 创建线程对象
print("main", threading.current_thread().name)
thread_1 = threading.Thread(target=sing)
thread_2 = threading.Thread(target=dance)
# 3. 启动线程
thread_1.start()
thread_2.start()
08-线程传参
# 1. 导包
import threading
import time
# 2.1 定义任务函数 唱歌
def sing(singer, song):
print("sing", threading.current_thread().name)
# 循环只执行了 5 次,在一个时间片内就执行结束了
for i in range(5):
print(f'singer正在唱歌 song.....')
time.sleep(0.1) # 让程序休眠 0.1秒, 进程会进入阻塞态,失去 CPU
# 2.2 跳舞
def dance(dancer, name):
print("dance", threading.current_thread().name)
for i in range(5):
print(f'dancer正在跳舞name....')
time.sleep(0.1)
if __name__ == '__main__':
# 2. 创建线程对象
print("main", threading.current_thread().name)
thread_1 = threading.Thread(target=sing, kwargs='singer': '毛不易', 'song': '消愁')
thread_2 = threading.Thread(target=dance, args=('罗老师', '精武门'))
# 3. 启动线程
thread_1.start()
thread_2.start()
09-线程的执行是无序的
# 1. 导包
import threading
import time
# 2.1 定义线程执行的任务函数
def func():
time.sleep(1)
print(threading.current_thread().name)
if __name__ == '__main__':
# 循环创建线程
for i in range(10):
# 2. 创建线程对象
sub_process = threading.Thread(target=func)
# 3. 启动线程
sub_process.start()
10-主线程会等待子线程结束在结束
import threading
import time
def func():
for i in range(5):
print(threading.current_thread().name, i)
time.sleep(0.5) # 2.5 s
print('子线程的任务结束')
if __name__ == '__main__':
sub_thread = threading.Thread(target=func)
sub_thread.start()
time.sleep(1)
print('主线程的任务结束了')
11-让子线程随着主线程的结束而结束
import threading
import time
def func():
for i in range(5):
print(threading.current_thread().name, i)
time.sleep(0.5) # 2.5 s
print('子线程的任务结束')
if __name__ == '__main__':
# 想让子线程随着主线程结束而结束,可以将子线程设置为 daemon 线程
# 方法一, 在创建对象的时候,设置
# sub_thread = threading.Thread(target=func, daemon=True)
sub_thread = threading.Thread(target=func)
# 方法二
# sub_thread.daemon = True
sub_thread.setDaemon(True)
sub_thread.start()
time.sleep(1)
print('主线程的任务结束了')
12-同一个进程中的线程共享全局变量
import threading
g_list = []
def write():
for i in range(5):
g_list.append(i)
print('添加数据', i)
print('write:', g_list)
def read():
print('read:', g_list)
if __name__ == '__main__':
write_thread = threading.Thread(target=write)
read_thread = threading.Thread(target=read)
write_thread.start()
read_thread.start()
print('main:', g_list)
13-线程共享全局变量的问题
import threading
# 定义全局变量
g_num = 0
# 定义任务函数
def func():
global g_num # 声明使用全局变量
for i in range(1000000):
g_num += 1
# 当子线程中的代码执行到此, 代表子线程的 100万次加 1 完成
print(threading.current_thread().name, g_num)
if __name__ == '__main__':
sub_thread1 = threading.Thread(target=func)
sub_thread2 = threading.Thread(target=func)
sub_thread1.start()
sub_thread2.start()
sub_thread1.join() # 等待线程 1 执行结束
sub_thread2.join() # 等待线程 2 执行结束
print('main:', g_num)
以上是关于我奶奶都能看懂系列016Python进程和线程的使用的主要内容,如果未能解决你的问题,请参考以下文章
我奶奶都能看懂系列007☀️python基础语法——函数,小学生也可以学!
我奶奶都能看懂系列002☀️python基础语法,小学生也可以学!
我奶奶都能看懂系列005☀️python基础语法——容器,小学生也可以学!