【python】多任务编程之线程、进程知识点详细总结

简介: 【python】多任务编程之线程、进程知识点详细总结

多任务的执行方式

进程

概念

python多进程

  • Windows下的main判断

  • process进程类

1. import multiprocessing
2. import time
3. def sing():
4. for i in range(3):
5. print(f"唱歌第{i}次")
6.         time.sleep(0.2)
7. def dance():
8. for i in range(3):
9. print(f"跳舞第{i}次")
10.         time.sleep(0.2)
11. if __name__ == '__main__':
12.     sing_pro = multiprocessing.Process(target=sing)
13.     dance_pro = multiprocessing.Process(target=dance)
14.     sing_pro.start()
15.     dance_pro.start()

注:此时唱歌和跳舞的优先度由系统调度决定(随机)

  • 获取进程id
1. import multiprocessing
2. import time
3. import os
4. def sing():
5. print('sing的父进程id:',os.getppid())
6. for i in range(3):
7. print(f"唱歌第{i}次")
8.         time.sleep(1)
9.         os.kill(os.getpid(),9)
10. #       强制结束进程
11. def dance():
12. for i in range(3):
13. print(f"跳舞第{i}次")
14.         time.sleep(1)
15. if __name__ == '__main__':
16.     sing_pro = multiprocessing.Process(target=sing)
17.     dance_pro = multiprocessing.Process(target=dance)
18. print("sing:", sing_pro)
19. print("dance:", dance_pro)
20.     sing_pro.start()
21.     dance_pro.start()
22. print("main:",os.getpid(),multiprocessing.current_process())

sing: <Process name='Process-1' parent=5920 initial>

dance: <Process name='Process-2' parent=5920 initial>

main: 5920 <_MainProcess name='MainProcess' parent=None started>

跳舞第0次

sing的父进程id: 5920

唱歌第0次

跳舞第1次

跳舞第2次

  • 带参任务的执行
1. import multiprocessing
2. def show(name,age):
3. print(f"姓名:{name},年龄是{age}岁")
4. if __name__ == '__main__':
5.     show_pro1=multiprocessing.Process(target=show("coleak1",19))
6.     show_pro2=multiprocessing.Process(target=show,args=('coleak2',20))
7.     show_pro3=multiprocessing.Process(target=show,kwargs={"age":21,"name":'coleak3'})
8.     show_pro1.start()
9.     show_pro2.start()
10.     show_pro3.start()

姓名:coleak1,年龄是19岁

姓名:coleak2,年龄是20岁

姓名:coleak3,年龄是21岁

  • 注意点
  1. 进程间全局变量不共享
  2. 主进程会等待所有子进程执行结束后再结束
  3. 进程之间执行是无序的,由操作系统调度决定
1. import multiprocessing
2. import time
3. import multiprocessing
4. my_list=list()
5. def add():
6. for i in range(3):
7.         my_list.append(i)
8. print("add:",i)
9.         time.sleep(0.5)
10. print(my_list)
11. def read():
12. print("read:",my_list)
13. if __name__ == '__main__':
14.     p1 = multiprocessing.Process(target=add)
15.     p2 = multiprocessing.Process(target=read)
16.     p1.start()
17.     p1.join()
18. #当前进程等待p1进程执行结束后再执行
19.     p2.start()
20. print("main:",my_list)

add: 0

add: 1

add: 2

[0, 1, 2]

main: []

read: []

1. import multiprocessing
2. import time
3. def test():
4. for i in range(6):
5. print(i)
6.         time.sleep(0.2)
7. if __name__ == '__main__':
8.     p1=multiprocessing.Process(target=test)
9.     p1.start()
10.     time.sleep(0.5)
11. print('over!')

0

1

2

over!

3

4

5

  • 主进程退出,子进程销毁
1. import multiprocessing
2. import time
3. def test():
4. while True:
5. print('执行ing...')
6.         time.sleep(0.2)
7. if __name__ == '__main__':
8.     p1=multiprocessing.Process(target=test)
9.     p1.daemon=True
10. # 子进程守护主进程
11.     p1.start()
12.     time.sleep(0.5)
13. print('over!')

执行ing...

执行ing...

执行ing...

over!

1. import multiprocessing
2. import time
3. def test():
4. while True:
5. print('执行ing...')
6.         time.sleep(0.2)
7. if __name__ == '__main__':
8.     p1=multiprocessing.Process(target=test,name='coleak')
9.     p1.start()
10.     time.sleep(0.5)
11.     p1.terminate()
12. print('over!')

执行ing...

执行ing...

执行ing...

over!

线程

概念

python多线程

1. import threading
2. import time
3. def sing():
4. for i in range(3):
5. print(f"唱歌第{i}次")
6.         time.sleep(0.2)
7. def dance():
8. for i in range(3):
9. print(f"跳舞第{i}次")
10.         time.sleep(0.2)
11. if __name__ == '__main__':
12.     t1=threading.Thread(target=sing)
13.     t2=threading.Thread(target=dance)
14.     t1.start()
15.     t2.start()

唱歌第0次跳舞第0次

唱歌第1次跳舞第1次

唱歌第2次跳舞第2次

1. import threading
2. import time
3. def test():
4.     t=threading.current_thread()
5. print('test:',t)
6. 
7. if __name__ == '__main__':
8. print("main:",threading.current_thread())
9.     t1=threading.Thread(target=test)
10.     t1.start()

main: <_MainThread(MainThread, started 3100)>

test: <Thread(Thread-1 (test), started 10836)>

  • 带参任务

同进程知识点

  • 注意点
  1. 线程之间执行是无序的,由cpu调度决定
  2. 主线程等子线程结束后再结束
  3. 线程之间共享全局变量
  4. 线程之间共享全局变量数据会出错
1. import threading
2. import time
3. def test():
4.     time.sleep(1)
5. print(threading.current_thread())
6. if __name__ == '__main__':
7. for i in range(20):
8.         t=threading.Thread(target=test)
9.         t.start()
  • demon守护主进程
1. import threading
2. import time
3. def test():
4. while True:
5. print('执行ing...')
6.         time.sleep(0.2)
7. if __name__ == '__main__':
8.     p1=threading.Thread(target=test,daemon=True)
9.     p1.start()
10.     time.sleep(0.5)
11. print('over!')
1. import threading
2. import time
3. def test():
4. while True:
5. print('执行ing...')
6.         time.sleep(0.2)
7. if __name__ == '__main__':
8.     p1=threading.Thread(target=test)
9.     p1.setDaemon(True)
10.     p1.start()
11.     time.sleep(0.5)
12. print('over!')

执行ing...

执行ing...

执行ing...

over!

1. import threading
2. import time
3. def test():
4. for i in range(3):
5.         my_list.append(i)
6. print("add:",i)
7. if __name__ == '__main__':
8.     my_list = list()
9.     p1=threading.Thread(target=test)
10.     p1.start()
11.     time.sleep(1)
12. print(my_list)

add: 0

add: 1

add: 2

[0, 1, 2]

1. import threading
2. import time
3. a=0
4. def test1():
5. global a
6. for i in range(1000000):
7.         a+=1
8. def test2():
9. global a
10. for i in range(1000000):
11.         a+=1
12. if __name__ == '__main__':
13.     p1=threading.Thread(target=test1)
14.     p2=threading.Thread(target=test2)
15.     p1.start()
16.     p2.start()
17. print(a)

993031,和正确结果相差了近7000

线程同步方式

线程等待

  • join

互斥锁

  • 概念

  • 使用

1. import threading
2. import time
3. a=0
4. lock=threading.Lock()
5. def test1():
6.     lock.acquire()
7. for i in range(1000000):
8. global a
9.         a+=1
10. # print(a)
11.     lock.release()
12. def test2():
13.     lock.acquire()
14. for i in range(1000000):
15. global a
16.         a+=1
17. # print(a)
18.     lock.release()
19. if __name__ == '__main__':
20.     p1=threading.Thread(target=test1)
21.     p2=threading.Thread(target=test2)
22.     p1.start()
23.     p2.start()
24.     time.sleep(2)
25. print(a,'over')

2000000 over

死锁

1. import threading
2. import time
3. lock=threading.Lock()
4. def get(index):
5.     my_list=[6,5,8,7]
6.     lock.acquire()
7. if index>=len(my_list):
8. print("下标越界",index)
9. return
10. print(my_list[index])
11.     lock.release()
12. 
13. if __name__ == '__main__':
14. for i in range(10):
15.         p=threading.Thread(target=get,args=(i,))
16.         p.start()

6

5

8

7

下标越界 4

  • 改进方案
1. import threading
2. import time
3. lock=threading.Lock()
4. def get(index):
5.     my_list=[6,5,8,7]
6.     lock.acquire()
7. if index>=len(my_list):
8. print("下标越界",index)
9.         lock.release()
10. return
11. print(my_list[index])
12.     lock.release()
13. 
14. if __name__ == '__main__':
15. for i in range(10):
16.         p=threading.Thread(target=get,args=(i,))
17.         p.start()

6

5

8

7

下标越界 4

下标越界 5

下标越界 6

下标越界 7

下标越界 8

下标越界 9

线程和进程对比

coleak
+关注
目录
打赏
0
0
0
0
47
分享
相关文章
|
6天前
|
[oeasy]python074_ai辅助编程_水果程序_fruits_apple_banana_加法_python之禅
本文回顾了从模块导入变量和函数的方法,并通过一个求和程序实例,讲解了Python中输入处理、类型转换及异常处理的应用。重点分析了“明了胜于晦涩”(Explicit is better than implicit)的Python之禅理念,强调代码应清晰明确。最后总结了加法运算程序的实现过程,并预告后续内容将深入探讨变量类型的隐式与显式问题。附有相关资源链接供进一步学习。
19 4
在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境
以上内容是一个简单的实现在Java后端中通过DockerClient操作Docker生成python环境并执行代码,最后销毁的案例全过程,也是实现一个简单的在线编程后端API的完整流程,你可以在此基础上添加额外的辅助功能,比如上传文件、编辑文件、查阅文件、自定义安装等功能。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境
Python 高级编程与实战:构建 RESTful API
本文深入探讨了使用 Python 构建 RESTful API 的方法,涵盖 Flask、Django REST Framework 和 FastAPI 三个主流框架。通过实战项目示例,详细讲解了如何处理 GET、POST 请求,并返回相应数据。学习这些技术将帮助你掌握构建高效、可靠的 Web API。
Python 高级编程与实战:构建自动化测试框架
本文深入探讨了Python中的自动化测试框架,包括unittest、pytest和nose2,并通过实战项目帮助读者掌握这些技术。文中详细介绍了各框架的基本用法和示例代码,助力开发者快速验证代码正确性,减少手动测试工作量。学习资源推荐包括Python官方文档及Real Python等网站。
Python 高级编程与实战:构建微服务架构
本文深入探讨了 Python 中的微服务架构,介绍了 Flask、FastAPI 和 Nameko 三个常用框架,并通过实战项目帮助读者掌握这些技术。每个框架都提供了构建微服务的示例代码,包括简单的 API 接口实现。通过学习本文,读者将能够使用 Python 构建高效、独立的微服务。
|
20天前
|
Linux 进程前台后台切换与作业控制
进程前台/后台切换及作业控制简介: 在 Shell 中,启动的程序默认为前台进程,会占用终端直到执行完毕。例如,执行 `./shella.sh` 时,终端会被占用。为避免不便,可将命令放到后台运行,如 `./shella.sh &`,此时终端命令行立即返回,可继续输入其他命令。 常用作业控制命令: - `fg %1`:将后台作业切换到前台。 - `Ctrl + Z`:暂停前台作业并放到后台。 - `bg %1`:让暂停的后台作业继续执行。 - `kill %1`:终止后台作业。 优先级调整:
35 5
探索Linux中的`ps`命令:进程监控与分析的利器
探索Linux中的`ps`命令:进程监控与分析的利器
179 13
掌握taskset:优化你的Linux进程,提升系统性能
在多核处理器成为现代计算标准的今天,运维人员和性能调优人员面临着如何有效利用这些处理能力的挑战。优化进程运行的位置不仅可以提高性能,还能更好地管理和分配系统资源。 其中,taskset命令是一个强大的工具,它允许管理员将进程绑定到特定的CPU核心,减少上下文切换的开销,从而提升整体效率。
掌握taskset:优化你的Linux进程,提升系统性能
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
255 4
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
探索进程调度:Linux内核中的完全公平调度器
【8月更文挑战第2天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。本文将深入探讨Linux内核中的完全公平调度器(Completely Fair Scheduler, CFS),一个旨在提供公平时间分配给所有进程的调度器。我们将通过代码示例,理解CFS如何管理运行队列、选择下一个运行进程以及如何对实时负载进行响应。文章将揭示CFS的设计哲学,并展示其如何在现代多任务计算环境中实现高效的资源分配。