【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

线程和进程对比

目录
相关文章
|
27天前
|
消息中间件 监控 Java
线程池关闭时未完成的任务如何保证数据的一致性?
保证线程池关闭时未完成任务的数据一致性需要综合运用多种方法和机制。通过备份与恢复、事务管理、任务状态记录与恢复、数据同步与协调、错误处理与补偿、监控与预警等手段的结合,以及结合具体业务场景进行分析和制定策略,能够最大程度地确保数据的一致性,保障系统的稳定运行和业务的顺利开展。同时,不断地优化和改进这些方法和机制,也是提高系统性能和可靠性的重要途径。
116 62
|
22天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
20天前
|
缓存 Java 调度
多线程编程核心:上下文切换深度解析
在现代计算机系统中,多线程编程已成为提高程序性能和响应速度的关键技术。然而,多线程编程中一个不可避免的概念就是上下文切换(Context Switching)。本文将深入探讨上下文切换的概念、原因、影响以及优化策略,帮助你在工作和学习中深入理解这一技术干货。
37 10
|
21天前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
50 12
|
22天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
15天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
15天前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
40 3
|
20天前
|
调度 开发者
深入理解:进程与线程的本质差异
在操作系统和计算机编程领域,进程和线程是两个核心概念。它们在程序执行和资源管理中扮演着至关重要的角色。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
42 5
|
20天前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
38 4
|
20天前
|
算法 调度 开发者
多线程编程核心:上下文切换深度解析
在多线程编程中,上下文切换是一个至关重要的概念,它直接影响到程序的性能和响应速度。本文将深入探讨上下文切换的含义、原因、影响以及如何优化,帮助你在工作和学习中更好地理解和应用多线程技术。
30 4
下一篇
DataWorks